在EditText中插入表情图片 (CharacterStyle&SpannableString)

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

Java代码   收藏代码
  1. Drawable drawable = getResources().getDrawable(id);  
  2.         drawable.setBounds(0 0 , drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());  
  3.         //需要处理的文本,[smile]是需要被替代的文本   
  4.         SpannableString spannable = new  SpannableString(getText().toString()+ "[smile]" );  
  5.         //要让图片替代指定的文字就要用ImageSpan   
  6.         ImageSpan span = new  ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);  
  7.         //开始替换,注意第2和第3个参数表示从哪里开始替换到哪里替换结束(start和end)   
  8. //最后一个参数类似数学中的集合,[5,12)表示从5到12,包括5但不包括12   
  9.         spannable.setSpan(span, getText().length(),getText().length()+"[smile]" .length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);    
  10.         setText(spannable);  
Drawable drawable = getResources().getDrawable(id);
		drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
		//需要处理的文本,[smile]是需要被替代的文本
		SpannableString spannable = new SpannableString(getText().toString()+"[smile]");
		//要让图片替代指定的文字就要用ImageSpan
        ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
        //开始替换,注意第2和第3个参数表示从哪里开始替换到哪里替换结束(start和end)
//最后一个参数类似数学中的集合,[5,12)表示从5到12,包括5但不包括12
        spannable.setSpan(span, getText().length(),getText().length()+"[smile]".length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);  
        setText(spannable);



将需要的文字高亮显示:

Java代码   收藏代码
  1. public   void  highlight( int  start, int  end){  
  2.         SpannableStringBuilder spannable=new  SpannableStringBuilder(getText().toString()); //用于可变字符串   
  3.         ForegroundColorSpan span=new  ForegroundColorSpan(Color.RED);  
  4.         spannable.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  5.         setText(spannable);  
  6.     }  
public void highlight(int start,int end){
		SpannableStringBuilder spannable=new SpannableStringBuilder(getText().toString());//用于可变字符串
		ForegroundColorSpan span=new ForegroundColorSpan(Color.RED);
		spannable.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		setText(spannable);
	}


加下划线:

Java代码   收藏代码
  1. public   void  underline( int  start, int  end){  
  2.         SpannableStringBuilder spannable=new  SpannableStringBuilder(getText().toString());  
  3.         CharacterStyle span=new  UnderlineSpan();  
  4.         spannable.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  5.         setText(spannable);  
  6.     }  
public void underline(int start,int end){
		SpannableStringBuilder spannable=new SpannableStringBuilder(getText().toString());
		CharacterStyle span=new UnderlineSpan();
		spannable.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		setText(spannable);
	}


组合运用:

Java代码   收藏代码
  1. SpannableStringBuilder spannable= new  SpannableStringBuilder(getText().toString());  
  2.         CharacterStyle span_1=new  StyleSpan(android.graphics.Typeface.ITALIC);  
  3.         CharacterStyle span_2=new  ForegroundColorSpan(Color.RED);  
  4.         spannable.setSpan(span_1, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  5.         spannable.setSpan(span_2, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  6.         setText(spannable);  
SpannableStringBuilder spannable=new SpannableStringBuilder(getText().toString());
		CharacterStyle span_1=new StyleSpan(android.graphics.Typeface.ITALIC);
		CharacterStyle span_2=new ForegroundColorSpan(Color.RED);
		spannable.setSpan(span_1, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		spannable.setSpan(span_2, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		setText(spannable);

 

Java代码   收藏代码
  1. /**  
  2.      * 带有\n换行符的字符串都可以用此方法显示2种颜色  
  3.      * @param text  
  4.      * @param color1  
  5.      * @param color2  
  6.      * @return  
  7.      */   
  8.     public  SpannableStringBuilder highlight(String text, int  color1, int  color2, int  fontSize){  
  9.         SpannableStringBuilder spannable=new  SpannableStringBuilder(text); //用于可变字符串   
  10.         CharacterStyle span_0=null ,span_1= null ,span_2;  
  11.         int  end=text.indexOf( "\n" );  
  12.         if (end==- 1 ){ //如果没有换行符就使用第一种颜色显示   
  13.             span_0=new  ForegroundColorSpan(color1);  
  14.             spannable.setSpan(span_0, 0 , text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  15.         }else {  
  16.             span_0=new  ForegroundColorSpan(color1);  
  17.             span_1=new  ForegroundColorSpan(color2);  
  18.             spannable.setSpan(span_0, 0 , end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  19.             spannable.setSpan(span_1, end+1 , text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  20.               
  21.             span_2=new  AbsoluteSizeSpan(fontSize); //字体大小   
  22.             spannable.setSpan(span_2, end+1 , text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  23.         }  
  24.         return  spannable;  
  25.     }  
/**
	 * 带有\n换行符的字符串都可以用此方法显示2种颜色
	 * @param text
	 * @param color1
	 * @param color2
	 * @return
	 */
	public SpannableStringBuilder highlight(String text,int color1,int color2,int fontSize){
		SpannableStringBuilder spannable=new SpannableStringBuilder(text);//用于可变字符串
		CharacterStyle span_0=null,span_1=null,span_2;
		int end=text.indexOf("\n");
		if(end==-1){//如果没有换行符就使用第一种颜色显示
			span_0=new ForegroundColorSpan(color1);
			spannable.setSpan(span_0, 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		}else{
			span_0=new ForegroundColorSpan(color1);
			span_1=new ForegroundColorSpan(color2);
			spannable.setSpan(span_0, 0, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			spannable.setSpan(span_1, end+1, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			
			span_2=new AbsoluteSizeSpan(fontSize);//字体大小
			spannable.setSpan(span_2, end+1, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		}
		return spannable;
	}


在EditText中插入表情图片 (CharacterStyle&SpannableString)_第1张图片

以上实际都是Html.fromHtml(html)的代码实现形式。

另外有个问题:如何让一个TextView中的关键字高亮显示?
http://www.eoeandroid.com/forum.php?mod=viewthread&tid=57880&page=1&extra=#pid558440
解决如下:

Java代码   收藏代码
  1. /**  
  2.      * 关键字高亮显示  
  3.      * @param target 需要高亮的关键字  
  4.      */   
  5.     public   void  highlight(String target){  
  6.         String temp=getText().toString();  
  7.         SpannableStringBuilder spannable = new  SpannableStringBuilder(temp);  
  8.         CharacterStyle span=null ;  
  9.           
  10.         Pattern p = Pattern.compile(target);  
  11.         Matcher m = p.matcher(temp);  
  12.         while  (m.find()) {  
  13.             span = new  ForegroundColorSpan(Color.RED); //需要重复!   
  14.             spannable.setSpan(span, m.start(), m.end(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  15.         }  
  16.         setText(spannable);  
  17.     }  
/**
	 * 关键字高亮显示
	 * @param target 需要高亮的关键字
	 */
	public void highlight(String target){
		String temp=getText().toString();
		SpannableStringBuilder spannable = new SpannableStringBuilder(temp);
		CharacterStyle span=null;
		
		Pattern p = Pattern.compile(target);
		Matcher m = p.matcher(temp);
		while (m.find()) {
			span = new ForegroundColorSpan(Color.RED);//需要重复!
			spannable.setSpan(span, m.start(), m.end(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		}
        setText(spannable);
	}


循环太慢,不知道有没有简单高效的方法?

在EditText中插入表情图片 (CharacterStyle&SpannableString)_第2张图片
付继承关系:

在EditText中插入表情图片 (CharacterStyle&SpannableString)_第3张图片

在EditText中插入表情图片 (CharacterStyle&SpannableString)_第4张图片

在EditText中插入表情图片 (CharacterStyle&SpannableString)_第5张图片

扩展学习:
android开发:TextView中显示HTML和图片
最近有人咨询我如何在TextView中显示<img src=""/> html标签内的图片,大家都知道,在TextView中显示HTML内容的方法如下所示:

Java代码   收藏代码
  1. TextView description=(TextView)findViewById(R.id.description);  
  2. description.setText(Html.fromHtml(item.getDescription()));  
TextView description=(TextView)findViewById(R.id.description);
description.setText(Html.fromHtml(item.getDescription()));


如果HTML中有图片的话,显示出来的图片会被一个小框取代,那么怎么样才能看到图片呢?查看了一下API,android.text.Html 还还有另一个方法:Html.fromHtml(String source,ImageGetter imageGetter,TagHandler tagHandler),这个方法使用如下所示:

Java代码   收藏代码
  1. ImageGetter imgGetter =  new  Html.ImageGetter() {  
  2.         public  Drawable getDrawable(String source) {  
  3.             Drawable drawable = null ;  
  4.             Log.d("Image Path" , source);  
  5.             URL url;  
  6.             try  {  
  7.                 url = new  URL(source);  
  8.                 drawable = Drawable.createFromStream(url.openStream(), "" );  
  9.             } catch  (Exception e) {  
  10.                 return   null ;  
  11.             }  
  12.             drawable.setBounds(0 0 , drawable.getIntrinsicWidth(), drawable  
  13.                     .getIntrinsicHeight());  
  14.             return  drawable;  
  15.         }  
  16.     };  
  17. .........  
  18. TextView description=(TextView)findViewById(R.id.description);  
  19. description.setText(Html.fromHtml(item.getDescription(),imgGetter,null ));  
ImageGetter imgGetter = new Html.ImageGetter() {
		public Drawable getDrawable(String source) {
			Drawable drawable = null;
			Log.d("Image Path", source);
			URL url;
			try {
				url = new URL(source);
				drawable = Drawable.createFromStream(url.openStream(), "");
			} catch (Exception e) {
				return null;
			}
			drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
					.getIntrinsicHeight());
			return drawable;
		}
	};
.........
TextView description=(TextView)findViewById(R.id.description);
description.setText(Html.fromHtml(item.getDescription(),imgGetter,null));


怎么样?很简单,第二个参数TagHandler是干什么的呢?从名称我们就知道是处理HTML中的标签的,比如说遇到某个标签就把它替换为….之类的操 作都可以通过TagHandler来处理,呵呵,我可没试过哦,瞎猜的,程序员一定要发挥充分的想像力,自己去试一下吧!

最后我要说的是,如果你的图片是从网络上获取的,那么你一定不要用这种方法显示一张图片,因为这是最垃圾的办法,你的程序会经常被卡死。

那么有没有更好的方法呢?

也许不是最好,但我建议您可以使用WebView来显示HTML内容。

你可能感兴趣的:(html,android,PHP,qq,咨询)