TextView + Spanned实现图文混排以及图片点击交互
最近要实现图文混排的需求,webview过大,所以想到了用SpannableStringBuilder来实现。 不过参考了大量国内文章,大多数是教你如何实现图文混排,并没有提及图片点击交互的。有翻阅了一些国外文章,说的也不是很详细,于是花费时间鼓捣了一下,最终实现了TextView图文混排,加点击交互的效果,在这里给大家分享下以免后来者在此处浪费过多时间。
主要用到的有Spanned ClickSpan ImageSpan ImagerGetter Html 。
先看一下效果图:
我把它封装成了一个控件,使用的时候只要将它放到xml布局
下载地址:https://github.com/githubwing/RichTextView
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.wingsofts.richtextview.MainActivity"
>
<com.wingsofts.richtextview.RichTextView
android:id="@+id/richTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
,然后
RichTextView richTextView = (RichTextView) findViewById(R.id.richTextView);
richTextView.setHtml(mTxt,1000,800);
richTextView.setOnImageClickListener(new RichTextView.ImageClickListener() {
@Override public void onImageClick(String imageUrl, String[] imageUrls, int position) {
Toast.makeText(MainActivity.this, "imageUrl :"+imageUrl+"\nimage size:"+imageUrls.length+"\n position:"+position, Toast.LENGTH_SHORT).show();
}
});
实现思路
由于后台是传来的html,所以可以借助系统类Html来解析生成Spanned,再将SpannedString转换为ClickSpan,最终实现图文混排+图片交互效果。
后台先传来一段html,如下:
String mTxt =
"<p>\r\n\t<span style=\"font-size:16px;\"><strong>比腾讯还土豪 传《阴阳师》项目组发60个月工资奖金</strong></span>\r\n</p>\r\n<p>\r\n\t<span style=\"font-size:16px;\"> 今日下午一则关于网易《阴阳师》项目组员工发60个月工资的奖金忽然在整个游戏圈流传,而以网易游戏平均10000以上的薪资水平来算,《阴阳师》项目组成员的奖金将达到60万元以上。"
+ "<img src=\"http://p2.pstatp.com/large/e220006a85a0b689eb8\" width=\"520\" height=\"216\" title=\"上证指数\" alt=\"上证指数\" />在游戏公司项目组发奖金较为平常,不过能够达到60个月工资的也就此前盛传的腾讯LOL项目组曾经打到过,包括几年之前被业界津津乐道的CF项目组都未曾有过这么高的规格。根据多家网站的数据和行业平均水平,网易游戏的平均薪资应该不会低于10000,这笔奖金的总额度可能创游戏行业有史以来最高。"
+ "</span>\r\n</p>\r\n<p>\r\n\t<span style=\"font-size:16px;\"><br />\r\n</span>\r\n</p>\r\n<p>\r\n\t<span style=\"font-size:16px;\"><img src=\"http://p3.pstatp.com/large/e1d000f89d603327470\" width=\"520\" height=\"216\" title=\"上证指数\" alt=\"上证指数\" />《阴阳师》是网易自研的3D和风卡牌RPG手游,同时该作也是一款二次元向手游,游戏9月2正式上架App Store,9月9日开始全平台公测,自上架以来该作就开始了传奇的冲榜之旅,到今天已经高居畅销榜第二名,仅次于长期包揽第一的同门师兄《梦幻西游》。\n"
+ "\n"
+ "<img src=\"http://p3.pstatp.com/large/e21000f51e83cb9b1c9\" width=\"520\" height=\"216\" title=\"上证指数\" alt=\"上证指数\" />";
之后利用Html.form()生成Spanned
stringBuilder = (SpannableStringBuilder) Html.fromHtml(source,
new GlideImageGetter(mContext, Glide.with(mContext), this, false, width, height), null);
注意这里的第二个参数,是一个ImageGetter类型的接口,这里直接拿了Glide作者开发的Imagegetter来使用,他的作用是在spanned中加载图片。
国内的文章大多介绍到这里,实现了图文混排。。。然后就没有然后了。。可是尼玛我想点击放大啊有没有。。 莫急,接下来就告诉你们,如何点击交互。
其实就是将Spanned转换为clickspan,
//从stringBuilder中读取图片
mImageSpans = stringBuilder.getSpans(0, stringBuilder.length(), ImageSpan.class);
//过滤出整个textView的所有图片
mImageUrls = new String[mImageSpans.length];
for (int i = 0; i < mImageSpans.length; i++) {
mImageUrls[i] = mImageSpans[i].getSource();
}
for (int i = 0; i < mImageSpans.length; i++) {
//获取图片span的起尾
int start = stringBuilder.getSpanStart(mImageSpans[i]);
int end = stringBuilder.getSpanEnd(mImageSpans[i]);
final int finalI = i;
//将span转化为clickspan
stringBuilder.setSpan(new ClickableSpan() {
@Override public void onClick(View widget) {
if (mImageClickListener != null) {
mImageClickListener.onImageClick(mImageUrls[finalI], mImageUrls, finalI);
}
}
}, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
嘛。。理论上这样就可以了,可是事实上,你会发现,点击图片根本没鸟反应!!!!!然后我有鼓捣了一会。。发现需要加上一句,才可以。
setMovementMethod(LinkMovementMethod.getInstance());
TextView + Spanned实现图文混排以及图片点击交互的更多相关文章
- DIV+CSS 图文混排的图片居中办法
不少人为了让 Div 图文混排的图片可以居中,给 IMG 套各式各样的 SPAN.DIV.LI 等等,以便于使用 text-align来进行居中. <div>图文混排 <br> ...
- iOS 图文混排 链接 可点击
对于这个话题 我想到 1 第一个解决方法就是使用 webView 比较经典 把所有复杂工作都交给控件本身去处理了, 但是好像好多需要自定义的地方 没法从 webView获得响应回调 :(估计也可以实 ...
- Unity插件之NGUI学习(5)—— 创建Label图文混排及文字点击
创建一个新的Scene,并按 Unity插件之NGUI学习(2)创建UI Root. 准备工作,制作Font.如今Project窗体创建一个Font目录.然后从系统自带字体目录中选择自己须要的字体,我 ...
- UILabel图文混排显示图片和文字
//传入文字 自动图片放在左边文字紧接着后排排布 -(void)setAttrDetailLabelWithTitle:(NSString *)title { NSMutableAttributedS ...
- HTML5[8]: 图文混排,图片与文字居中对齐
<img src="image.png"><span>999</span> img { /* ... */ vertical-align: t ...
- TextView中的图文混排
ImageSpan imageSpanMenu1 = new ImageSpan(activity,menuResId1); SpannableString contentMenu1 = new Sp ...
- [UGUI]图文混排(六):点击区域
点击区域可以分成两部分来分析: 0.Rect 搜索api:Rect和Rect.Rect,可以知道: 在GUI和GUILayout中,Rect的原点在左上角,向右为x轴正方向,向下为y轴正方向: 除此之 ...
- CoreText实现图文混排之文字环绕及点击算法
系列文章: CoreText实现图文混排:http://www.jianshu.com/p/6db3289fb05d CoreText实现图文混排之点击事件:http://www.jianshu.co ...
- Android中Textview显示Html,图文混排,支持图片点击放大
本文首发于网易云社区 对于呈现Html文本来说,Android提供的Webview控件可以得到很好的效果,但使用Webview控件的弊端是效率相对比较低,对于呈现简单的html文本的话,杀鸡不必使用牛 ...
随机推荐
- IOS开发- 访问通讯录,并将通讯录中姓名-头像-手机号码 发给服务器
现在很多软件都会访问通讯录,并将通讯录的信息取得,发给服务器,然后服务器会返回相应电话号码的用户是否注册. 现在分享一下前两步,访问通讯录并处理通讯录的信息 1.导入框架 #import <Ad ...
- [HAOI2016]找相同字符
题目描述 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. 输入输出格式 输入格式: 两行,两个字符串s1,s2,长度分别为 ...
- [POI2007]POW-The Flood
题目描述 给定一张地势图,所有的点都被水淹没,现在有一些关键点,要求放最少的水泵使所有关键点的水都被抽干 输入输出格式 输入格式: In the first line of the standard ...
- bzoj4946 Noi2017 蔬菜
题目描述 小 N 是蔬菜仓库的管理员,负责设计蔬菜的销售方案. 在蔬菜仓库中,共存放有nn 种蔬菜,小NN 需要根据不同蔬菜的特性,综合考虑各方面因素,设计合理的销售方案,以获得最多的收益. 在计算销 ...
- poj 1367 robot(搜索)
题意:给你一个图,求起点 到 终点的最少时间 每次有两种选择①:往前走1~3步 ②原地选择90° 费时皆是1s 图中1为障碍物,而且不能出边界.还要考虑机器人的直径 ...
- linux tracepoint用法【转】
转自:https://blog.csdn.net/u014089131/article/details/73907995 在kernel中经常会看到trace_XX形式的函数,但是又找不到它的定义. ...
- Python【第二课】 字符串,列表,字典,集合,文件操作
本篇内容 字符串操作 列表,元组操作 字典操作 集合操作 文件操作 其他 1.字符串操作 1.1 字符串定义 特性:不可修改 字符串是 Python 中最常用的数据类型.我们可以使用引号('或&quo ...
- 基于SSM框架实现简单的登录注册
一.环境配置 工程目录 在pom.xml添加依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=& ...
- laravel实现支付宝支付功能
起因 前段时间因为项目中需要实现支付宝手机网站支付功能,所以写下这篇文章以作记录,不足之处,欢迎指教. 后端框架:Laravel 5.5 业务功能 适用于商家在移动端网页应用中集成支付宝支付功能.商家 ...
- MySQL使用判断
1.case语法 在第一个方案的返回结果中, value=compare-value.而第二个方案的返回结果是第一种情况的真实结果.如果没有匹配的结果值,则返回结果为ELSE后的结果,如果没有ELSE ...