HtmlSpanner使用小结

来源:互联网 发布:大数据 曾是规划 编辑:程序博客网 时间:2024/06/01 13:35

HtmlSpanner是一个能够把Html源代码解析成spannablestring的开源库.

基本的使用方法很简单,使用 
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());            }        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

然后需要注册该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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

自定义的ClickableImageSpan

public abstract class ClickableImageSpan extends ImageSpan {    public ClickableImageSpan(Drawable b) {        super(b);    }    public abstract void onClick(View view);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

自定义的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;    }}
原创粉丝点击