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文本的话,杀鸡不必使用牛 ...
随机推荐
- [LeetCode] Longest Continuous Increasing Subsequence 最长连续递增序列
Given an unsorted array of integers, find the length of longest continuous increasing subsequence. E ...
- 做了两年多salesforce平台开发,转Java的经历
2015年毕业,转眼已经三年多了.三年对于现在的我,真的很快,一开始对软件开发的执着一直没有变.我是一个很普通很普通长沙的一个专科毕业.刚进大学,对于软件开发真的是小白,仅仅只是存在对于游戏,和桌面软 ...
- [NOI 2010]超级钢琴
Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙 的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙 ...
- 【USACO】AC自动机
Description 对,这就是裸的AC自动机. 要求:在规定时间内统计出模版字符串在文本中出现的次数. Input 第一行:模版字符串的个数N. 第2->N+1行:N个字符串.(每个模版字符 ...
- 【luogu P4007 清华集训2017】小Y和恐怖奴隶主
题目背景 “A fight? Count me in!” 要打架了,算我一个. “Everyone, get in here!” 所有人,都过来! 题目描述 小 Y 是一个喜欢玩游戏的 OIer.一天 ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
- poj 1279 半平面交核面积
Art Gallery Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6668 Accepted: 2725 Descr ...
- hdu 5532(最长上升子序列)
Input The first line contains an integer T indicating the total number of test cases. Each test case ...
- [Noi2013]书法家
来自FallDream的博客,未经允许,请勿转载,谢谢. 小E同学非常喜欢书法,他听说NOI2013已经开始了,想题一幅“NOI”的字送给大家. 小E有一张非常神奇的纸,纸可以用一个n 行m 列的二维 ...
- 《Java技术》的第二次作业
(一)学习总结 1.什么是构造方法?什么是构造方法的重载?下面的程序是否可以通过编译?为什么? (1) 构造方法用于在创建对象时对其进行初始化,且方法名与类名相同,方法名前面没有返回值类型的声明,不能 ...