最近要实现图文混排的需求,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实现图文混排以及图片点击交互的更多相关文章

  1. DIV+CSS 图文混排的图片居中办法

    不少人为了让 Div 图文混排的图片可以居中,给 IMG 套各式各样的 SPAN.DIV.LI 等等,以便于使用 text-align来进行居中. <div>图文混排 <br> ...

  2. iOS 图文混排 链接 可点击

    对于这个话题 我想到 1 第一个解决方法就是使用 webView 比较经典 把所有复杂工作都交给控件本身去处理了,  但是好像好多需要自定义的地方 没法从 webView获得响应回调 :(估计也可以实 ...

  3. Unity插件之NGUI学习(5)—— 创建Label图文混排及文字点击

    创建一个新的Scene,并按 Unity插件之NGUI学习(2)创建UI Root. 准备工作,制作Font.如今Project窗体创建一个Font目录.然后从系统自带字体目录中选择自己须要的字体,我 ...

  4. UILabel图文混排显示图片和文字

    //传入文字 自动图片放在左边文字紧接着后排排布 -(void)setAttrDetailLabelWithTitle:(NSString *)title { NSMutableAttributedS ...

  5. HTML5[8]: 图文混排,图片与文字居中对齐

    <img src="image.png"><span>999</span> img { /* ...  */ vertical-align: t ...

  6. TextView中的图文混排

    ImageSpan imageSpanMenu1 = new ImageSpan(activity,menuResId1); SpannableString contentMenu1 = new Sp ...

  7. [UGUI]图文混排(六):点击区域

    点击区域可以分成两部分来分析: 0.Rect 搜索api:Rect和Rect.Rect,可以知道: 在GUI和GUILayout中,Rect的原点在左上角,向右为x轴正方向,向下为y轴正方向: 除此之 ...

  8. CoreText实现图文混排之文字环绕及点击算法

    系列文章: CoreText实现图文混排:http://www.jianshu.com/p/6db3289fb05d CoreText实现图文混排之点击事件:http://www.jianshu.co ...

  9. Android中Textview显示Html,图文混排,支持图片点击放大

    本文首发于网易云社区 对于呈现Html文本来说,Android提供的Webview控件可以得到很好的效果,但使用Webview控件的弊端是效率相对比较低,对于呈现简单的html文本的话,杀鸡不必使用牛 ...

随机推荐

  1. 初学servlet之@WebServlet传参

    package app01a;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletCon ...

  2. codevs 3061 质子撞击炮②

    提交地址:http://codevs.cn/problem/3016/ 3016 质子撞击炮 II  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold     题目描 ...

  3. [HNOI 2002]营业额统计

    Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每 ...

  4. [HAOI2011]向量

    题目描述 给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个向量 ...

  5. 【NOIP 2017】宝藏

    Description 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋 ...

  6. bzoj4152[AMPPZ2014]The Captain 最短路

    4152: [AMPPZ2014]The Captain Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1517  Solved: 603[Submi ...

  7. 2015 ICL, Finals, Div. 1 Ceizenpok’s formula(组合数取模,扩展lucas定理)

    J. Ceizenpok’s formula time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  8. C语言程序设计第一次作业(2017.10.10完成)

    一:程序框图以及正确运行结果: (1)给出圆半径,得出圆面积: ①程序框图如下: ②测试图如下: 经过测试 ,输入半径2能得出正确结果.多次测试,输入不同值,均得出正确结果,证明稳定性. ③实验分析: ...

  9. java 第三次作业

    (一)学习总结 1.阅读下面程序,分析是否能编译通过?如果不能,说明原因.应该如何修改?程序的运行结果是什么?为什么子类的构造方法在运行之前,必须调用父 类的构造方法?能不能反过来? class Gr ...

  10. C++标准库之stack

    C++库以提供"模板"为主.所谓模板,是指不必预先制定类型的函数或类.我们可以借助STL(标准模板库 Standard Template Library, STL)提供的高效算法来 ...