HtmlSpanner使用小结
2016-07-23 18:14
225 查看
HtmlSpanner是一个能够把Html源代码解析成spannablestring的开源库.
基本的使用方法很简单,使用
注意,fromHtml方法不能够在主线程中调用.
其他一些功能
1.能够获取标签属性和自定义标签属性,使用工具,HtmlCleaner,这个工具网上资料比较多。
2.handlers,HtmlSpanner提供了很多Handlers用于对不同标签进行处理。
3.spans,HtmlSpanner提供了多个span能够使用。
4.css
我 以动态添加可以点击的imagespan为例,介绍handlers的用法。
在activity中创建自己的HtmlSpanner
存在这么一个需求:加载html文档到本地,通过HtmlSpanner解析成spannablestring,显示,并且能够使里面的image可点击,并执行点击事件。
我们需要 htmlspanner
TagNodeHandler
其实这里的TagNodeHandler使用的是HtmlSpanner中的ImageHandler(ImageHandler是处理img标签的handler)只是改了部分代码,更适合我使用而已 你也可以参考ImageHandler的源码创建自己的ImageHandler
然后需要注册该handler
之后调起线程处理html
最后得到结果
自定义的ClickableImageSpan
自定义的ClickableMovementMethod 。是这样的,网上某大神添加可点击的imagespan,发现imagespan是不能点击的,然后他翻了LinkMovementMethod的源码,发现里面只检测了ClickableSpan的点击事件,所以他改了一些东西,写了个ClickableMovementMethod,的东西,只需要调用
ClickableMovementMethod 源码
b7d1
基本的使用方法很简单,使用
new HtmlSpanner().fromHtml(content);// content是html源代码
注意,fromHtml方法不能够在主线程中调用.
其他一些功能
1.能够获取标签属性和自定义标签属性,使用工具,HtmlCleaner,这个工具网上资料比较多。
2.handlers,HtmlSpanner提供了很多Handlers用于对不同标签进行处理。
3.spans,HtmlSpanner提供了多个span能够使用。
4.css
我 以动态添加可以点击的imagespan为例,介绍handlers的用法。
在activity中创建自己的HtmlSpanner
存在这么一个需求:加载html文档到本地,通过HtmlSpanner解析成spannablestring,显示,并且能够使里面的image可点击,并执行点击事件。
我们需要 htmlspanner
private HtmlSpanner htmlSpanner = new HtmlSpanner();
TagNodeHandler
其实这里的TagNodeHandler使用的是HtmlSpanner中的ImageHandler(ImageHandler是处理img标签的handler)只是改了部分代码,更适合我使用而已 你也可以参考ImageHandler的源码创建自己的ImageHandler
private TagNodeHandler tagNodeHandler = new TagNodeHandler() { @Override public void handleTagNode(TagNode node, final SpannableStringBuilder builder, final int start, final int end, final SpanStack spanStack) { final String src = node.getAttributeByName("src"); imageUrls[imageCount] = src; imageCount ++; builder.append("\uFFFC"); Bitmap loadBitmap = loadBitmap(src); int toHeight = loadBitmap.getHeight() * textViewWidth / loadBitmap.getWidth(); Bitmap bitmap = Bitmap.createScaledBitmap(loadBitmap, textViewWidth, toHeight, true); if (bitmap != null) { Drawable drawable = new BitmapDrawable(bitmap); drawable.setBounds(0, 0, bitmap.getWidth() - 1, bitmap.getHeight() - 1); spanStack.pushSpan(new ClickableImageSpan(drawable) { @Override public void onClick(View view) { // do your job } }, start, builder.length()); } }
然后需要注册该handler
htmlSpanner.registerHandler("img", tagNodeHandler);
之后调起线程处理html
new GetHtmlSpannerThread(mHandler, htmlSpanner, content).start();
最后得到结果
case KEY_GET_HTML_SPANNER_SUC: Spannable spannable = (Spannable) msg.obj; if (null != spannable){ tv_detail_intro.setText(spannable); } else{ tv_detail_intro.setText("加载失败"); } break;
自定义的ClickableImageSpan
public abstract class ClickableImageSpan extends ImageSpan { public ClickableImageSpan(Drawable b) { super(b); } public abstract void onClick(View view); }
自定义的ClickableMovementMethod 。是这样的,网上某大神添加可点击的imagespan,发现imagespan是不能点击的,然后他翻了LinkMovementMethod的源码,发现里面只检测了ClickableSpan的点击事件,所以他改了一些东西,写了个ClickableMovementMethod,的东西,只需要调用
tv_detail_intro.setMovementMethod(new ClickableMovementMethod());,就可以使上面定义的ClickableImageSpan可被点击了。
ClickableMovementMethod 源码
public class ClickableMovementMethod extends LinkMovementMethod { private static ClickableMovementMethod sInstance; public static ClickableMovementMethod getInstance() { if (sInstance == null) { sInstance = new ClickableMovementMethod(); } return sInstance; } public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { int x = (int) event.getX(); int y = (int) event.getY(); x -= widget.getTotalPaddingLeft(); y -= widget.getTotalPaddingTop(); x += widget.getScrollX(); y += widget.getScrollY(); Layout layout = widget.getLayout(); int line = layout.getLineForVertical(y); int off = layout.getOffsetForHorizontal(line, x); ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); ClickableImageSpan[] imageSpans = buffer.getSpans(off, off, ClickableImageSpan.class); if (link.length != 0) { if (action == MotionEvent.ACTION_UP) { link[0].onClick(widget); } else if (action == MotionEvent.ACTION_DOWN) { Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); } return true; } else if (imageSpans.length != 0) { if (action == MotionEvent.ACTION_UP) { imageSpans[0].onClick(widget); } else if (action == MotionEvent.ACTION_DOWN) { Selection.setSelection(buffer, buffer.getSpanStart(imageSpans[0]), buffer.getSpanEnd(imageSpans[0])); } return true; } else { Selection.removeSelection(buffer); } } return false; } }
b7d1
相关文章推荐
- Andriod开发中常见问题
- Android利用Intent启动和关闭Activity
- html5 App phonegapcn + eclipse + Andriod 安装配置
- android原生的数据库实现[ContentProvider+SQLiteOpenHelpe...
- TextView的日常使用技巧
- Andriod Intent的详细解释深入 Android 【四】 —— 组件调用
- Android学习笔记(一)Windows XP 下Android开发环境搭建
- Android软件安全开发实践(下)
- Android(1.5及以上版本) 开机图片/文字/动画分析
- Android 根文件系统启动分析
- cocos2d-x场景切换时内存过高导致crash 解决方法
- Android消息推送机制
- eclipse制作app入门教程
- 苏州园区新企业广邀软件工程师加入
- 北京友好互动科技发展有限公司招聘信息(实习和全职均招)
- Android Listview显示混乱问题
- Android错误笔记1
- zxing生成解析二维码以及二维码生成解析的一个Android应用程序
- VirtualBox安装Android_x86无法连接网络
- Eclipse andriod avd模拟器老是终止!!!!