android html格式转化为TextView支持的Spanned

html格式转化为TextView支持的Spanned

Spanned spanned = Html.fromHtml(html, getter, new MessageTagHandler());

html:html的字符串

getter(ImageGetter):图片的转换器

public abstract static interface android.text.Html$ImageGetter {
  
  public abstract android.graphics.drawable.Drawable getDrawable(java.lang.String arg0);

}
ImageGetter imgGetter = new Html.ImageGetter() {
           @Override
           public Drawable getDrawable(String source) {
             
               Drawable d=null;
               try
                  {
               URL aryURI = new URL(source);
               /* 打开连接 */
               URLConnection conn = aryURI.openConnection();
               conn.connect();
               /* 转变为 InputStream */
               InputStream is = conn.getInputStream();
               /* 将InputStream转变为Bitmap */
               //Bitmap bm = BitmapFactory.decodeStream(is);
               /* 关闭InputStream */
              
               /*添加图片*/
                d=Drawable.createFromStream(is, "111");
                is.close();
                  } catch (IOException e)
                  {
                    e.printStackTrace();
                  }
             d.setBounds(1, 1, 45, 45);
               return d;
           }

传入的参数为image标签的souce属性,一般为url地址

MessageTagHandler(TagHandler):特殊标签处理

public abstract static interface android.text.Html$TagHandler {

  public void handleTag(boolean opening, String tag, Editable output,

            XMLReader xmlReader)
}

接口被调用的过程:

系统在解析html文本

发现tag时调用一次 如<html>
接口传递的参数为 handleTag(true,”html”,output , xmlReader )

发现tag的闭合时,调用接口
接口传递的参数为 handleTag(false,”html”,output , xmlReader )

public class MyHtmlTagHandler implements TagHandler {

       public void handleTag(boolean opening, String tag, Editable output,
                XMLReader xmlReader) {
            if(tag.equalsIgnoreCase("strike") || tag.equals("s")) {
                processStrike(opening, output);
            }
        }

        private void processStrike(boolean opening, Editable output) {
            int len = output.length();
            if(opening) {
                output.setSpan(new StrikethroughSpan(), len, len, Spannable.SPAN_MARK_MARK);
            } else {
                Object obj = getLast(output, StrikethroughSpan.class);
                int where = output.getSpanStart(obj);

                output.removeSpan(obj);

                if (where != len) {
                    output.setSpan(new StrikethroughSpan(), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
        }

        private Object getLast(Editable text, Class kind) {
            Object[] objs = text.getSpans(0, text.length(), kind);

            if (objs.length == 0) {
                return null;
            } else {
                for(int i = objs.length;i>0;i--) {
                    if(text.getSpanFlags(objs[i-1]) == Spannable.SPAN_MARK_MARK) {
                        return objs[i-1];
                    }
                }
                return null;
            }
        }

}

自定义Span

public class StrikethroughSpan extends ClickableSpan {

    private OnMyListener mListener;

    @Override
    public void onClick(View widget) {
        if (mListener != null) {
            mListener.onReply();
        }
    }

    public void setOnMyListener(OnReplyListener l) {
        mListener = l;
    }

    public interface OnMyListener {
        public void OnMy();
    }

}

把Spanned放到android的TextView控件上展示

    private void initHtmlTextView(TextView text, Spanned spanned) {
        SpannableStringBuilder ssb = new SpannableStringBuilder(spanned);
        StrikethroughSpan[] replySpans = ssb.getSpans(0, spanned.length(), StrikethroughSpan.class);
        for (final StrikethroughSpan span : replySpans) {
            span.setOnMyListener(new OnMyListener () {
                @Override
                public void OnMy() {
                   ……
                }
            });
        }
        URLSpan[] spans = ssb.getSpans(0, spanned.length(), URLSpan.class);
        for (final URLSpan span : spans) {
            int start = ssb.getSpanStart(span);
            int end = ssb.getSpanEnd(span);
            int flags = ssb.getSpanFlags(span);
            ClickableSpan span2 = new ClickableSpan() {
                @Override
                public void onClick(View widget) {
                    String url = span.getURL();
                    ……
                }
            };
            ssb.removeSpan(span);
            ssb.setSpan(span2, start, end, flags);
        }
        ImageSpan[] imageSpans = ssb.getSpans(0, spanned.length(), ImageSpan.class);
        final ArrayList<String> urls = new ArrayList<String>();
        for (final ImageSpan span : imageSpans) {
            int start = ssb.getSpanStart(span);
            int end = ssb.getSpanEnd(span);
            int flags = ssb.getSpanFlags(span);
            final String url = span.getSource();
            urls.add(url);
            ClickableSpan span2 = new ClickableSpan() {
                @Override
                public void onClick(View widget) {
                    ……
                }
            };
            ClickableSpan[] click_spans = ssb.getSpans(start, end, ClickableSpan.class);
            if (click_spans.length != 0) {
                for (ClickableSpan c_span : click_spans) {
                    ssb.removeSpan(c_span);
                }
            }
            ssb.setSpan(span2, start, end, flags);
        }
        text.setText(ssb);
        text.setMovementMethod(TextViewFixTouchConsume.LocalLinkMovementMethod.getInstance());
    }

 

转载于:https://www.cnblogs.com/xbx2015/p/5498268.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值