EditText通常用于显示文字,但有时候也需要在文字中夹杂一些图片,比如QQ中就可以使用表情图片,又比如需要的文字高亮显示等等,如何在android中也做到这样呢? 
记得android中有个android.text包,这里提供了对文本的强大的处理功能。 

添加图片主要用SpannableStringImageSpan类,具体参考sdk文档 SpannableString


这里以人人网客户端发布消息的界面为例


布局文件main.xml

<?xml version="1.0" encoding="utf-8"?>                                                                                    

MainActivity.java

package com.yulore.emotion;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.inputmethod.InputMethodManager;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.BaseAdapter;import android.widget.EditText;import android.widget.GridView;import android.widget.ImageButton;import android.widget.ImageView;public class MainActivity extends Activity implements OnClickListener {    private static final String TAG = "MainActivity";private ImageButton ib_emotion;private GridView gv_emotion;private EmotionAdapter mAdapter;private EditText et_content;private ImageView iv_publish;/** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                findViewById();        initEmotionIcons();        setListener();                mAdapter = new EmotionAdapter();        gv_emotion.setAdapter(mAdapter);    }private void initEmotionIcons() {String json = EmotionUtil.getInstance().readFromFile(EmotionUtil.DOWNLOAD_EMOTION_PATH, "Emoticons.json");if(json!=null){Log.e(TAG, json);RenRenData.mEmotionList = new DataProvider().resolve(json);}}private void findViewById() {ib_emotion = (ImageButton) findViewById(R.id.newsfeedpublish_emoticon);gv_emotion = (GridView) findViewById(R.id.newsfeedpublish_emoticons);et_content = (EditText) findViewById(R.id.newsfeedpublish_content);iv_publish = (ImageView) findViewById(R.id.newsfeedpublish_publish);}private void setListener() {ib_emotion.setOnClickListener(this);et_content.setOnClickListener(this);gv_emotion.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {String emotion = RenRenData.mEmotionList.get(position).getEmotion();if(et_content.getText().length()+emotion.length()<=140){//长度小于140//et_content.setText(et_content.getText().toString()+emotion);CharSequence ret = EmotionUtil.getInstance().replace(getApplicationContext(), et_content.getText().toString()+emotion);Log.e(TAG, "ret="+ret);et_content.setText(ret);}}});}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.newsfeedpublish_emoticon:if(gv_emotion.isShown()){gv_emotion.setVisibility(View.GONE);ib_emotion.setImageResource(R.drawable.v5_0_1_publisher_emotion_button);}else{gv_emotion.setVisibility(View.VISIBLE);ib_emotion.setImageResource(R.drawable.v5_0_1_publisher_pad_button);//隐藏输入法界面InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);imm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);}break;case R.id.newsfeedpublish_content:if(gv_emotion.isShown()){gv_emotion.setVisibility(View.GONE);ib_emotion.setImageResource(R.drawable.v5_0_1_publisher_emotion_button);}break;default:break;}}private class EmotionAdapter extends BaseAdapter{@Overridepublic int getCount() {return RenRenData.mEmotionList.size();}@Overridepublic Object getItem(int position) {return RenRenData.mEmotionList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view;ViewHolder holder;if(convertView==null){holder = new ViewHolder();view = View.inflate(getApplicationContext(), R.layout.emotion_item, null);holder.iv_emotion = (ImageView) view.findViewById(R.id.emotcons_item_img);view.setTag(holder);}else{view = convertView;holder = (ViewHolder) view.getTag();}EmotionIcon em = RenRenData.mEmotionList.get(position);holder.iv_emotion.setImageBitmap(EmotionUtil.getInstance().getLocalEmotionIcon(em.getEmotion()));return view;}}public static class ViewHolder{public ImageView iv_emotion;}}


EmotionUtil.java

package com.yulore.emotion;import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.regex.Matcher;import java.util.regex.Pattern;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Environment;import android.text.Spannable;import android.text.SpannableStringBuilder;import android.text.style.ImageSpan;public class EmotionUtil {public static final String DOWNLOAD_EMOTION_PATH = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/RenRenForAndroid/Emoticons/";private static EmotionUtil instance = new EmotionUtil();private EmotionUtil() {};public static EmotionUtil getInstance() {return instance;}/** * 将文本中的表情符号替换为表情图片 *  * @param text *            需要转换的字符 * @return 带有表情的字符 */public CharSequence replace(Context context,CharSequence text) {try {SpannableStringBuilder builder = new SpannableStringBuilder(text);Pattern pattern = buildPattern();Matcher matcher = pattern.matcher(text);while (matcher.find()) {Bitmap bitmap = getLocalEmotionIcon(matcher.group());ImageSpan span = new ImageSpan(context, bitmap);builder.setSpan(span, matcher.start(), matcher.end(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);}return builder;} catch (Exception e) {return text;}}/** * 正则表达式 *  * @return */private Pattern buildPattern() {/** * 查看表情名称数据是否存在,不存在则从本地读取Json,并解析 */if(RenRenData.mEmotionList==null || RenRenData.mEmotionList.size()==0){String json = EmotionUtil.getInstance().readFromFile(EmotionUtil.DOWNLOAD_EMOTION_PATH, "Emoticons.json");if(json!=null){RenRenData.mEmotionList = new DataProvider().resolve(json);}}StringBuilder patternString = new StringBuilder(RenRenData.mEmotionList.size() * 3);patternString.append('(');for (EmotionIcon result : RenRenData.mEmotionList) {String s = result.getEmotion();patternString.append(Pattern.quote(s));patternString.append('|');}patternString.replace(patternString.length() - 1,patternString.length(), ")");return Pattern.compile(patternString.toString());}public String readFromFile(String filePath, String fileName) {if (fileName == null || "".equals(fileName)) {return null;}String ret = "";if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {File dir = new File(filePath);if (dir == null || !dir.exists()) {dir.mkdirs();}File targetFile = new File(filePath + fileName);try {if (targetFile == null || targetFile.exists()) {targetFile.createNewFile();}InputStream in = new BufferedInputStream(new FileInputStream(targetFile));BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));String tmp;while ((tmp = br.readLine()) != null) {ret += tmp;}br.close();in.close();} catch (IOException e) {e.printStackTrace();}}return ret;}/** * 根据表情名称查找表情图片 * @param imageName * @return */public Bitmap getEmotionIcon(String imageName) {File cacheDir = new File(DOWNLOAD_EMOTION_PATH);if (!cacheDir.exists()) {cacheDir.mkdirs();}File[] cacheFiles = cacheDir.listFiles();int i = 0;if (cacheFiles != null) {for (; i < cacheFiles.length; i++) {if (imageName.equals(cacheFiles[i].getName())) {break;}}}if (i < cacheFiles.length) {return BitmapFactory.decodeFile(DOWNLOAD_EMOTION_PATH + imageName);}return null;}/** * 从SD卡中根据表情符号获取表情图片 *  * @param imageName *            表情的名称 * @return 表情的Bitmap */public Bitmap getLocalEmotionIcon(String imageName) {File dir = new File(DOWNLOAD_EMOTION_PATH);if (!dir.exists()) {dir.mkdirs();}File[] cacheFiles = dir.listFiles();int index = 0;for (int i = 0; cacheFiles != null && i < cacheFiles.length; i++) {if (imageName.equals(cacheFiles[i].getName())) {index = i;break;}}Bitmap bitmap = null;if (index < cacheFiles.length) {/** * 因表情图片较小,则这里返回了一个60*60的Bitmap,该数值可根据情况调整 */bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeFile(DOWNLOAD_EMOTION_PATH+ imageName), 60, 60, true);}return bitmap;}/** * 将文本中的表情符号转换为表情图片 *  * @param text * @return *//*public CharSequence replace02(Context context, CharSequence text, int resId) {// SpannableString连续的字符串,长度不可变,同时可以附加一些object;可变的话使用SpannableStringBuilder,参考sdk文档SpannableString ss = new SpannableString(text.toString() + "[smile]");// 得到要显示图片的资源Drawable d = context.getResources().getDrawable(resId);// 设置高度d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());// 跨度底部应与周围文本的基线对齐ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);// 附加图片ss.setSpan(span, text.length(), text.length() + "[smile]".length(),Spannable.SPAN_INCLUSIVE_EXCLUSIVE);return ss;}*/}







更多相关文章

  1. Android(安卓)Bitmap的加载和Cache
  2. Android(安卓)开发 调用图库选择图片实现和参数详解
  3. android Matrix 操作
  4. 图说Android开机画面和开机动画
  5. 【Android】ViewPager实现图片左右滑动播放及添加点击事件
  6. android瀑布流简单实现原理
  7. Android(安卓)Picasso 图片加载库基础使用详解
  8. [转] Android(安卓)TextView处理HTML标签、显示图片等
  9. OpenCV 的 RGB 顺序和 Android(安卓)载入的 RGB 顺序相反

随机推荐

  1. AllJoyn+Android开发案例-android跨设备
  2. android默认开启adb调试方法分析
  3. Android(安卓)计时器Timer用法
  4. 一起Talk Android吧(第二百六十三回:Androi
  5. Android菜鸟实训的第二天--视图容器组件A
  6. 【Android您问我讲】Android(安卓)2.x中
  7. 知识小结(Android)
  8. Android对话框
  9. Android应用程序线程消息循环
  10. Android(安卓)Property System | Android