一、介绍
这是新浪微博的一个帖子,刚好包括了话题、表情、@好友三种显示。显示方法上篇已经阐述了,就是使用SpannableString。这篇主要介绍显示这种帖子的解析工具类。
二、实现
1.字符串表示和对应正则表达式
话题用##号括起来
表情用[]表示
@好友昵称
借助正则匹配来解析帖子信息。
话题 -> #[^#]+#
表情 -> [[^]]+]
@好友 -> @好友昵称
2.写一个通用方法,对spanableString进行正则判断,如果符合要求,则将内容变色
private static voID dealPattern(int color,SpannableString spannableString,Pattern patten,int start) throws Exception { Matcher matcher = patten.matcher(spannableString); while (matcher.find()) { String key = matcher.group(); // 返回第一个字符的索引的文本匹配整个正则表达式,ture 则继续递归 if (matcher.start() < start) { continue; } // 计算该内容的长度,也就是要替换的字符串的长度 int end = matcher.start() + key.length(); //设置前景色span spannableString.setSpan(new ForegroundcolorSpan(color),matcher.start(),end,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); if (end < spannableString.length()) { // 如果整个字符串还未验证完,则继续。。 dealPattern(color,spannableString,patten,end); } break; } }
3.应为有些是可点击的,所以需要一个方法来处理可点击的内容
①先定义一个接口,通过接口的方式将点击事件交给调用者
public interface SpanClickListener<T>{ voID onSpanClick(T t); }
②写一个通用方法,对spanableString进行正则判断,如果符合要求,将内容设置可点击
private static voID dealClick(SpannableString spannableString,int start,final SpanClickListener spanClickListener,final Object bean){ Matcher matcher = patten.matcher(spannableString); while (matcher.find()) { String key = matcher.group(); // 返回第一个字符的索引的文本匹配整个正则表达式,ture 则继续递归 if (matcher.start() < start) { continue; } // 计算该内容的长度,也就是要替换的字符串的长度 int end = matcher.start() + key.length(); spannableString.setSpan(new ClickableSpan() { @OverrIDe public voID onClick(VIEw Widget) { spanClickListener.onSpanClick(bean); } @OverrIDe public voID updateDrawState(TextPaint ds) { super.updateDrawState(ds); //设置画笔属性 ds.setUnderlineText(false);//默认有下划线 } },Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); if (end < spannableString.length()) { // 如果整个字符串还未验证完,则继续。。 dealClick(spannableString,spanClickListener,bean); } break; } }
4.表情解析方法(后面会写一篇关于表情的处理)
private voID dealExpression(Context context,int start) throws Exception { Matcher matcher = patten.matcher(spannableString); while (matcher.find()) { String key = matcher.group(); if (matcher.start() < start) { continue; } String value = emojiMap.get(key); if (TextUtils.isEmpty(value)) { continue; } // 通过上面匹配得到的字符串来生成图片资源ID int resID = context.getResources().getIDentifIEr(value,"drawable",context.getPackagename()); if (resID != 0) { Drawable emoji = context.getResources().getDrawable(resID); int w = (int) (emoji.getIntrinsicWIDth() * 0.40); int h = (int) (emoji.getIntrinsicHeight() * 0.40); emoji.setBounds(0,w,h); // 通过图片资源ID来得到bitmap,用一个ImageSpan来包装 ImageSpan imageSpan = new ImageSpan(emoji); // 计算该图片名字的长度,也就是要替换的字符串的长度 int end = matcher.start() + key.length(); // 将该图片替换字符串中规定的位置中 spannableString.setSpan(imageSpan,Spannable.SPAN_INCLUSIVE_EXCLUSIVE); if (end < spannableString.length()) { dealExpression(context,end); } break; } } }
5.关键词变色处理方法,这个实际中的使用场景比如地图关键字搜索,匹配到关键字的地址中关键字显示特别颜色
public static SpannableString getKeyWordSpan(int color,String str,String patterStr) throws Exception { SpannableString spannableString = new SpannableString(str); Pattern patten = Pattern.compile(patterStr,Pattern.CASE_INSENSITIVE); dealPattern(color,0); return spannableString; }
6.话题处理,参数中需要传入话题对象。这里只处理了一个帖子中只有一个话题的情况
public static SpannableString gettopicSpan(int color,boolean clickable,SpanClickListener spanClickListener,topic topic) throws Exception { SpannableString spannableString = new SpannableString(str); Pattern patten = Pattern.compile(PatternString.topIC_PATTERN,Pattern.CASE_INSENSITIVE); if(clickable){ dealClick(spannableString,topic); } dealPattern(color,0); return spannableString; }
7.@好友处理,参数中需要传入@的好友列表
public static SpannableString getAtUserSpan(int color,List<User> atUsers) throws Exception { SpannableString spannableString = new SpannableString(str); Pattern patten; for (User u : atUsers) { patten = Pattern.compile("@" + u.getname(),Pattern.CASE_INSENSITIVE); if(clickable){ dealClick(spannableString,u); } dealPattern(color,0); } return spannableString; }
8.表情处理,就这么简洁
public static SpannableString getExpressionSpan(Context context,String str) throws Exception { return ExpressionConvertUtil.getInstace().getExpressionString(context,str); }
三、使用
1.关键字变色
private voID testcoloredKeywd() { String string = "AndroID一词的本义指“机器人”,同时也是Google于2007年11月5日,AndroID logo相关图片,AndroID logo相关图片(36张)\n"; SpannableString cardText = null; try { cardText = SpanUtils.getKeyWordSpan(getResources().getcolor(R.color.md_green_600),string,"AndroID"); } catch (Exception e) { e.printstacktrace(); } tvcoloredKeywd.setText(cardText); }
2.话题测试,需要注意的是,让部分内容可点击需要设置tvtopic.setMovementMethod(linkMovementMethod.getInstance());,否则点击无效果
private voID testtopic() { String topic = "#舌尖上的大连#四种金牌烤芝士吃法爱吃芝士的盆友不要错过了~L秒拍视频\n"; SpannableString topicText = null; try { topicText = SpanUtils.gettopicSpan(color.BLUE,topic,true,new SpanUtils.SpanClickListener<topic>() { @OverrIDe public voID onSpanClick(topic t) { Toast.makeText(MainActivity.this,"点击话题:" + t.toString(),Toast.LENGTH_SHORT).show(); } },new topic(1,"舌尖上的大连")); } catch (Exception e) { e.printstacktrace(); } tvtopic.setText(topicText); //如果想实现点击,必须要设置这个 tvtopic.setMovementMethod(linkMovementMethod.getInstance()); }
3.@好友测试
private voID textAtUsers(){ List<User> users = new ArrayList<>(); users.add(new User(1,"好友1")); users.add(new User(2,"好友2")); StringBuilder sb = new StringBuilder("快来看看啊"); for (User u : users) { sb.append("@").append(u.getname()); } sb.append("\n"); try { SpannableString atSpan = SpanUtils.getAtUserSpan(color.BLUE,sb.toString(),new SpanUtils.SpanClickListener<User>() { @OverrIDe public voID onSpanClick(User user) { Toast.makeText(MainActivity.this,"@好友:" + user.toString(),users); tvTestAt.setText(atSpan); tvTestAt.setMovementMethod(linkMovementMethod.getInstance()); } catch (Exception e) { e.printstacktrace(); } }
4.表情测试
private voID textExpression(){ String exStr = "今天天气很好啊[呲牙],是不是应该做点什么[色]"; SpannableString span = null; try { span = SpanUtils.getExpressionSpan(this,exStr); } catch (Exception e) { e.printstacktrace(); } tvExpression.setText(span); }
效果图
下载:https://github.com/LineChen/SpannableStringDemo
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
以上是内存溢出为你收集整理的Android仿新浪微博、QQ空间等帖子显示(2)全部内容,希望文章能够帮你解决Android仿新浪微博、QQ空间等帖子显示(2)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)