本帖最后由 丁佼 于 2016-1-26 10:24 编辑
2.2. 匹配#话题#或@联系人,并提供点击响应。 2.2.1. 使用正则表达式确定start和end位置 从之前的代码可以看到,设置文字点击监听的代码是固定不变的,比较费脑的是怎么确定start和end的位置。#话题#和@联系人都是固定格式的字符串,查找固定格式的字符串应使用正则表达式来处理。上代码:
/** * 将字符串内容的#话题#设置为可点击,并放入TextView</br> * 搜索关键字:SpannableString,ClickableSpan</br> * @param msgSpan 需要传入SpannableString对象,此方法使用完后还要继续添加@联系人的的点击处理,要共用同一个对象 */ public static void setTopicSpan(TextView textView, SpannableString msgSpan) { // 参数1 #话题#使用的正则表达式,正则验证网站 : http://tool.chinaz.com/regex/ String topicPatternStr = "#(.+?)#";
// 参数2 使用正则表达式创建查询对象 Pattern topicPattern = Pattern.compile(topicPatternStr);
// 参数3 使用正则查找出msgSpan里所有的话题 Matcher matcher = topicPattern.matcher(msgSpan); while (matcher.find()) { // matcher.group() 的返回值为匹配出来的字符串 String topicName = matcher.group(); Log.e(TAG, "start=" + matcher.start() + ";end=" + matcher.end() + ";话题为:=" + topicName);
// 自定义的ClickableSpan,构造方法里接收话题字符串 ClickableSpan clickableSpan = new TopicClickableSpan(topicName); // 设置点击 msgSpan.setSpan(clickableSpan, matcher.start(), matcher.end(), SpannableString.SPAN_INCLUSIVE_EXCLUSIVE); }
textView.setText(msgSpan); textView.setMovementMethod(LinkMovementMethod.getInstance()); } |
2.2.2. 参数1,,正则表达式的查询规则 本文不做讲解,有需要请自行搜索“正则表达式”。 2.2.3. 参数2,参数3,Pattern和Matcher 都是JDK里用于处理正则表达式的类,使用方法是固定的,可以参见代码注释。 2.2.4. TopicClickableSpan 继承自ClickableSpan,由于ClickableSpan的onClick方法参数为View,无法区分出被点击的span,需要在构造方法里传递话题字符串以供区分不同的话题。 private static class TopicClickableSpan extends ClickableSpan {
private String topic;
/** 由于ClickableSpan的onClick方法参数为View,无法区分出被点击的span,只能在构造方法里传递话题字符串以供区分 */ private TopicClickableSpan(String topic){ this.topic = topic; }
public void onClick(View widget) { Toast.makeText(widget.getContext(), "被点击的话题是:"+topic, 1).show(); } }; |
2.2.5. @联系人的点击处理 更换正则表达式和自定义的ClickableSpan即可。 3. emoji表情的显示处理3.1. ImageSpan 可以将文字替换为图片显示,接收的图片可以是资源id也可以是Bitmap。 3.2. Emoji表情 从服务器传过来的只是字符串,但是应该具备类似[/吓死]或者/xs这样的特殊格式,客户端通过正则表达式确定表情字符串的start和end位置,将文字转换为图片并显示到文本框。
int emojiResId = EmojiList.findEmoji(emojiName); if (emojiResId != -1) { // 参数4 如果查询到图片则将SpannableString里表情文字替换为图片 ImageSpan emojiSpan = new ImageSpan(textView.getContext(), emojiResId); msgSpan.setSpan(emojiSpan, matcher.start(), matcher.end(), SpannableString.SPAN_INCLUSIVE_EXCLUSIVE); } |
3.3. EmojiList类 根据匹配到的表情名称查找出来的对应图片id。用于封装所有的表情资源 4. 将超链接转换为图片,并提供点击处理通过正则表达式匹配到URL的start和end位置,并且同时设置ImageSpan和ClickableSpan到该段字符上,使得该段字符串同时具备两种特性
msgSpan.setSpan(httpPicSpan, start, end, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
msgSpan.setSpan(clickableSpan,start,end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE); |
|