Android仿新浪微博、QQ空间等帖子显示(2)

Android仿新浪微博、QQ空间等帖子显示(2),第1张

概述一、介绍这是新浪微博的一个帖子,刚好包括了话题、表情、@好友三种显示。显示方法上篇已经阐述了,就是使用SpannableString。这篇主要介绍显示这种帖子的解析工具类。

一、介绍

这是新浪微博的一个帖子,刚好包括了话题、表情、@好友三种显示。显示方法上篇已经阐述了,就是使用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)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1148044.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存