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

一、介绍

这是新浪微博的一个帖子,刚好包括了话题、表情、@好友三种显示。显示方法上篇已经阐述了,就是使用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, Pattern patten, 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);//默认有下划线 } }, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); if (end < spannableString.length()) { // 如果整个字符串还未验证完,则继续。。 dealClick(spannableString, patten, end, spanClickListener, bean); } break; } }

4.表情解析方法(后面会写一篇关于表情的处理)

private void dealExpression(Context context, SpannableString spannableString, Pattern patten, 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, 0, w, h); // 通过图片资源id来得到bitmap,用一个ImageSpan来包装 ImageSpan imageSpan = new ImageSpan(emoji); // 计算该图片名字的长度,也就是要替换的字符串的长度 int end = matcher.start() + key.length(); // 将该图片替换字符串中规定的位置中 spannableString.setSpan(imageSpan, matcher.start(), end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); if (end < spannableString.length()) { dealExpression(context, spannableString, patten, 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, spannableString, patten, 0); return spannableString; }

6.话题处理,参数中需要传入话题对象。这里只处理了一个帖子中只有一个话题的情况

public static SpannableString getTopicSpan(int color, String str, 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, patten, 0, spanClickListener, topic); } dealPattern(color, spannableString, patten, 0); return spannableString; }

7.@好友处理,参数中需要传入@的好友列表

public static SpannableString getAtUserSpan(int color, String str, boolean clickable, SpanClickListener spanClickListener, 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, patten, 0, spanClickListener, u); } dealPattern(color, spannableString, patten, 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(), true, new SpanUtils.SpanClickListener<User>() { @Override public void onSpanClick(User user) { Toast.makeText(MainActivity.this, "@好友:" + user.toString(), Toast.LENGTH_SHORT).show(); } }, 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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-09-28 01:52:20

Android仿新浪微博、QQ空间等帖子显示(2)的相关文章

Android仿新浪微博/QQ空间滑动自动播放视频功能_Android

先来看看效果图 关键代码 1.监听滚动事件 首先要给listview添加setOnScrollListener监听,注意这个监听在recyclerView上是addOnScrollListener,也就是说下面代码同时支持recyclerView. public int firstVisible=0,visibleCount=0, totalCount=0; videoList.setOnScrollListener(new AbsListView.OnScrollListener() { @O

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

一.介绍 这是新浪微博的一个帖子,刚好包括了话题.表情.@好友三种显示.显示方法上篇已经阐述了,就是使用SpannableString.这篇主要介绍显示这种帖子的解析工具类. 二.实现 1.字符串表示和对应正则表达式 话题用##号括起来 表情用[]表示 @好友昵称 借助正则匹配来解析帖子信息. 话题 -> #[^#]+# 表情 -> [[^]]+] @好友 -> @好友昵称 2.写一个通用方法,对spanableString进行正则判断,如果符合要求,则将内容变色 private sta

基于zepto.js实现仿手机QQ空间的大图查看组件ImageView.js详解

 这篇文章主要介绍了基于zepto.js实现仿手机QQ空间的大图查看组件ImageView.js的源码和使用方法,并附上一个使用ImageView.js的实例,这里分享给大家,有需要的小伙伴参考下.     调用方式 :ImageView(index,imgData) --index参数 为图片默认显示的索引值,类型 为Number --imaData参数 为图片url数组 ,类型为Array 使用之前要先引入 zepto.js 文件 ImageView.js具体代码如下:   代码如下: /*

Android仿微信QQ设置图形头像裁剪功能_Android

最近在做毕业设计,想有一个功能和QQ一样可以裁剪头像并设置圆形头像,额,这是设计狮的一种潮流. 而纵观现在主流的APP,只要有用户系统这个功能,这个需求一般都是在(bu)劫(de)难(bu)逃(xue)! 图片裁剪实现方式有两种,一种是利用系统自带的裁剪工具,一种是使用开源工具Cropper.本节就为大家带来如何使用系统自带的裁剪工具进行图片裁剪~ 还是先来个简单的运行图. 额,简单说下,我待会会把代码写成小demo分享给大家,在文章末尾会附上github链接,需要的可以自行下载~ 下面来简单分

Android仿新浪微博分页管理界面(3)

本文实例为大家分享了Android仿新浪微博分页管理界面的具体代码,供大家参考,具体内容如下 多个activity分页管理,为了方便获取上下文,采用继承TabActivity的传统方法. 大致思路:使用RadioGroup点击触发不同的选卡项,选卡项绑定不同的activiity,进而进行分页管理.详解见注解. /** * 主Activity * 通过点击RadioGroup下的RadioButton来切换不同界面 * Created by D&LL on 2016/7/20. */ public

Android仿微信QQ设置图形头像裁剪功能

最近在做毕业设计,想有一个功能和QQ一样可以裁剪头像并设置圆形头像,额,这是设计狮的一种潮流. 而纵观现在主流的APP,只要有用户系统这个功能,这个需求一般都是在(bu)劫(de)难(bu)逃(xue)! 图片裁剪实现方式有两种,一种是利用系统自带的裁剪工具,一种是使用开源工具Cropper.本节就为大家带来如何使用系统自带的裁剪工具进行图片裁剪~ 还是先来个简单的运行图. 额,简单说下,我待会会把代码写成小demo分享给大家,在文章末尾会附上github链接,需要的可以自行下载~ 下面来简单分

Android仿手机QQ图案解锁功能

本文实例为大家分享了Android仿手机QQ图案解锁的具体代码,供大家参考,具体内容如下 ps:请不要再问我,为什么导入之后会乱码了. 其实,代码基本上都是从原生系统中提取的:LockPatternView.加密工具类,以及解锁逻辑等,我只是稍作修改,大家都知道,原生系统界面比较丑陋,因此,我特意把QQ的apk解压了,从中拿了几张图案解锁的图片,一个简单的例子就这样诞生了. 好了,废话不多说,我们来看看效果(最后两张是最新4.4系统,炫一下,呵呵): 1.最关健的就是那个自定义九宫格View,代

QQ空间无法正常显示怎么办?

原因分析 出现这种问题可能是flash插件安装失败或己过期不兼容了 网页缓存的问题,因为可能QQ空间更新了js,css我们 缓存就会调用老的内容所以清除即可. 解决办法 1.在电脑中安装一个"QQ电脑管家",然后打开它,如下图所示 2.在电脑管家界面我们找到"电脑诊所"下面的"QQ专区",如下图所示. 3.然后进入到了QQ专区我们找到第一个"QQ空间无法正常显示"进入之后点击"立即修复即可.

QQ空间提示无法显示该网页怎么回事?

解决方案一 一.清空IE缓存; 二.安全设置; 三.添加受信任站点; 四.设置隐私; 五.退出杀毒软件.防火墙.上网助手,取消浏览器屏蔽设置. 六.重置浏览器. 解决方案二,既然是QQ的产品我们可以尝试使用QQ电脑管家来解决 1.打开你电脑中安装的QQ电脑管家,然后点击它打开之后点击"工具箱"如下所示   2.在工具箱点击"电脑诊所"如下图所示   3.进入之后我们在右上角的搜索框搜索"QQ空间打不开" 如下所示 4.然后我们点击第一个修复方案&