最近要实现图文混排的需求,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. java设计模式之单例设计模式和多例设计模式

    单例设计模式:构造方法私有化,在类的内部定义static属性和方法,利用static方法来取得本类的实例化对象:无论外部产生多少个实例化对象,本质上只有一个实例化对象 饿汉式单例设计 class Si ...

  2. Java集合详解二

    前一篇我们已经讲过了Collectin是存放单值的最大接口, 可以看到Map接口和其主要之类的关系图如下: 快速访问 HashMap    HashTable  TreeMap  Map输出 那Map ...

  3. [SDOI 2012]Longge的问题

    Description Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N). Input 一 ...

  4. [JSOI2008]球形空间产生器

    Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧 ...

  5. [HNOI2011]任务调度

    题目描述 有 N 个任务和两台机器 A 与 B.每个任务都需要既在机器 A 上执行,又在机器 B 上执行, 第 i 个任务需要在机器 A 上执行时间 Ai,且需要在机器 B 上执行时间 Bi.最终的目 ...

  6. [BZOJ]4197: [Noi2015]寿司晚宴

    Time Limit: 10 Sec  Memory Limit: 512 MB Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NO ...

  7. 2015 多校联赛 ——HDU5386(暴力)

    Sample Input 1 3 5 2 2 1 2 3 3 2 1 3 3 3 3 3 3 3 3 3 3 H 2 3 L 2 2 H 3 3 H 1 3 L 2 3   Sample Output ...

  8. [SDOI2009]Bill的挑战

    题目描述 题解: 因为要求的T长度一定,可定义f[i][j] 为前i位状态为j的方案,can[i][j]表示第i为字母j,可行的状态 每次往后推就行了 #include <algorithm&g ...

  9. hdu 4052 线段树扫描线、奇特处理

    Adding New Machine Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  10. hdu5634 BestCoder Round #73 (div.1)

    Rikka with Phi  Accepts: 5  Submissions: 66  Time Limit: 16000/8000 MS (Java/Others)  Memory Limit: ...