Android-微博客户端在TextView中把富文本转换成表情图片

  在上一篇随笔中记录了在微博正文的TextView中高亮部分关键字(@人名、#话题#和http短链接)的方法,这次的笔记记录如何实现表情功能,并把TextView中的[表情]转换成图片表情

  目前比较流行的有两种方法:

  第一种是调用新浪提供的API:https://api.weibo.com/2/emotions.json  通过icon或者url字段把表情图片download下来,接着对富文本进行转换。

  第二种是把表情图片都下载到本地,直接放入drawable资源文件夹里,通过phrase和表情名字(与down下来的图片名字要一致)的对应进行转换。

  为了效率的缘故,本项目采用第二种。至于怎么下载图片不详细展开,此次笔记着重于富文本与表情图片的转换在微博项目中的应用。

   

 1     /**
 2      * 高亮部分文本与表情的转换
 3      * 
 4      * @param content
 5      *            文本内容
 6      * @return
 7      */
 8     public static SpannableString setTextHighLightAndTxtToImg(String content,
 9             Context context) {
10         SpannableString result = new SpannableString(content);
11 
12         //高亮文本部分代码省略
13         
14         if(content.contains("[")&&content.contains("]")){
15             Pattern p = Pattern.compile(Constants.regex_emoji);
16             Matcher m = p.matcher(result);
17             while(m.find()){
18                 int start = m.start();
19                 int end = m.end();
20                 String phrase = content.substring(start, end);
21                 String imageName = "";
22                 List<Emotions> list = MainActivity.emotionList;
23                 for (Emotions emotions : list) {
24                     if (emotions.getPhrase().equals(phrase)) {
25                         imageName = emotions.getImageName();
26                     }
27                 }
28                 try {
29                     Field f = (Field) R.drawable.class
30                             .getDeclaredField(imageName);
31                     int i = f.getInt(R.drawable.class);
32                     Drawable drawable = context.getResources().getDrawable(i);
33                     if (drawable != null) {
34                         drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
35                                 drawable.getIntrinsicHeight());
36                         ImageSpan span = new ImageSpan(drawable,
37                                 ImageSpan.ALIGN_BASELINE);
38                         result.setSpan(span, start, end,
39                                 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
40                     }
41                 } catch (SecurityException e) {
42                     e.printStackTrace();
43                 } catch (NoSuchFieldException e) {
44                     e.printStackTrace();
45                 } catch (IllegalArgumentException e) {
46                     e.printStackTrace();
47                 } catch (IllegalAccessException e) {
48                 }
49                 
50             }
51             
52         }
53 
54         return result;
55     }

  算法思想:TextView中的[xxx]编码正则表达式遍历出来,每一个编码都与MainActivity.emotionList中的每一个Emotions实例的phrase字段进行对比,遇到相同的则查找drawable中ImageName与phrase对应的表情图片,转换的具体函数用到

ImageSpan这个API。

 其中MainActivity.emotionList这个List<Emotions>是Emotions实体类的列表,Emotions实体类则是根据2/emotions这个新浪官方表情接口的返回信息而设置的存储类。
 Emotions的实体类如下
 1 public class Emotions implements Serializable{
 2 
 3     /**
 4      * 
 5      */
 6     private static final long serialVersionUID = 1L;
 7     
 8     /** 表情使用的替代文字 */
 9     private String phrase;
10     /** 表情图片类型 */
11     private String type;
12     /** 表情图片存放的位置 */
13     private String url;
14     /** 是否为热门表情 */
15     private String isHot;
16     /** 是否属于通用 */
17     private String isCommon;
18     /** 表情分类 */
19     private String category;
20     /** 表情名称 */
21     private String imageName;
22 
23     public String getPhrase() {
24         return phrase;
25     }
26 
27     public void setPhrase(String phrase) {
28         this.phrase = phrase;
29     }
30 
31     public String getType() {
32         return type;
33     }
34 
35     public void setType(String type) {
36         this.type = type;
37     }
38 
39     public String getUrl() {
40         return url;
41     }
42 
43     public void setUrl(String url) {
44         this.url = url;
45     }
46 
47     public String getIsHot() {
48         return isHot;
49     }
50 
51     public void setIsHot(String isHot) {
52         this.isHot = isHot;
53     }
54 
55     public String getIsCommon() {
56         return isCommon;
57     }
58 
59     public void setIsCommon(String isCommon) {
60         this.isCommon = isCommon;
61     }
62 
63     public String getCategory() {
64         return category;
65     }
66 
67     public void setCategory(String category) {
68         this.category = category;
69     }
70 
71     public String getImageName() {
72         return imageName;
73     }
74 
75     public void setImageName(String imageName) {
76         this.imageName = imageName;
77     }
78 
79 }

 

  至于MainActivity.emotionList怎么来的则如下

 1 public static List<Emotions> emotionList = new ArrayList<Emotions>();
 2 
 3 /** 初始化表情列表 */
 4     private void initEmotionsList() {
 5         String[] emotions_phrase = getResources().getStringArray(
 6                 R.array.emotions_phrase);
 7         String[] emotions_imagename = getResources().getStringArray(
 8                 R.array.emotions_imagename);
 9         Emotions emotions;
10         for (int i = 0; i < 72; i++) {
11             emotions = new Emotions();
12             emotions.setImageName(emotions_imagename[i]);
13             emotions.setPhrase(emotions_phrase[i]);
14             emotionList.add(emotions);
15         }
16     }

  关于R.array.emotions_phraseR.array.emotions_imagename两个数组,只能自己去收集了少年

  效果图过几天放上来,手机因为测试刷微博而没流量了

  

  5.26补上效果图两张:

  Android-微博客户端在TextView中把富文本转换成表情图片_第1张图片

你可能感兴趣的:(textview)