标签:
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()); }
标签:
原文地址:http://www.cnblogs.com/xbx2015/p/5498268.html