Android TextView显示表情、标签、超链接

Android TextView显示表情图片、标签、超链接

因为项目需求,要在用户发布动态的时候可以打上标签,超链接,还有图片标签,本来不打算写这篇博客,在查阅资料的时候我发现网上的博客都是类似的,大家你抄我,我抄你,抄来抄去,这就是所谓的拿来主义吧,盗版在国内太过泛滥,不多说,切入正题,先来看下我们今天研究的效果图
Android TextView显示表情、标签、超链接_第1张图片
我研究了下微博和QQ的动态,发现他们的内容描述都有一个共同点——用html写的?,我查了些资料,主要涉及到以下问题:

  • 1、TextView是如何处理html
  • 2、TextView是如何显示html中图片的
  • 3、TextView是如何处理html中的超链接、标签的点击问题
  • 4、如果有自定义标签,该如何处理
    既然明确的问题,接下来我们来一个个解决

来看下我们今天要用到的API:

public static Spanned fromHtml (String source)  
public static Spanned fromHtml (String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)  
public static String toHtml (Spanned text) 

来看看具体的实现


    String html = "

点击打开我的博客diy_coder

"
+ "

这个#搞笑视频#笑死我了,哈哈,快来看看" + "@生活如此多娇

"
+ "

云音乐福利

"
// + "

"
+ "

"
; private static final int TOPIC_TAG = 0; private static final int AT_USER = 1; private static final int NORMAL_URL = 2; private static final int CUSTOM_TAG = 3; private Context mContext; private TextView tv_html; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = this; tv_html = (TextView) findViewById(R.id.tv_html); tv_html.setText(getClickableHtml(html)); tv_html.setClickable(true); tv_html.setMovementMethod(LinkMovementMethod.getInstance()); } private CharSequence getClickableHtml(String html) { Spanned spannedHtml = Html.fromHtml(html, mImageGetter, new CustomTagHandler()); SpannableStringBuilder clickableHtmlBuilder = new SpannableStringBuilder(spannedHtml); URLSpan[] urls = clickableHtmlBuilder.getSpans(0, spannedHtml.length(), URLSpan.class); for (final URLSpan span : urls) { int start = clickableHtmlBuilder.getSpanStart(span); int end = clickableHtmlBuilder.getSpanEnd(span); int flag = clickableHtmlBuilder.getSpanFlags(span); final String url = span.getURL(); setUpUrl(clickableHtmlBuilder, span, start, end, flag, url); } return clickableHtmlBuilder; } private void setUpUrl(SpannableStringBuilder clickableHtmlBuilder, URLSpan span, int start, int end, int flag, final String url) { CustomClickableSpan clickableSpan = null; if (url.startsWith("@")) { clickableSpan = new CustomClickableSpan(AT_USER, url); } else if (url.startsWith("#")) { clickableSpan = new CustomClickableSpan(TOPIC_TAG, url); } else if (url.startsWith("http") || url.startsWith("https")) { clickableSpan = new CustomClickableSpan(NORMAL_URL, url); } clickableHtmlBuilder.removeSpan(span);//清除当前span clickableHtmlBuilder.setSpan(clickableSpan, start, end, flag); } //处理点击事件 class CustomClickableSpan extends ClickableSpan { String text; int type; public CustomClickableSpan(int type, String text) { this.text = text; this.type = type; } @Override public void updateDrawState(TextPaint ds) { int color = getResources().getColor(R.color.blue); ds.setColor(color);//设置点击文字的颜色 ds.setUnderlineText(false); //去掉下划线 } @Override public void onClick(View widget) { //点击事件处理 Intent intent = null; switch (type) { case AT_USER://@用户 intent = new Intent(mContext, UserActivity.class); intent.putExtra("userId", text); break; case TOPIC_TAG://#话题# intent = new Intent(mContext, TopicActivity.class); intent.putExtra("topic", text); break; case NORMAL_URL://网页 intent = new Intent(mContext, WebActivity.class); intent.putExtra("url", text); break; case CUSTOM_TAG://自定义标签 intent = new Intent(mContext, CustomTagActivity.class); intent.putExtra("tag", text); break; } startActivity(intent); } } //处理自定义标签 class CustomTagHandler implements Html.TagHandler { private int startIndex = 0; private int stopIndex = 0; @Override public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { if (tag.toLowerCase().equals("tag")) {//自定义标签处理 if (opening) {//开始标签 startTag(tag, output, xmlReader); } else {//结束标签 endTag(tag, output, xmlReader); } } } public void startTag(String tag, Editable output, XMLReader xmlReader) { startIndex = output.length(); } public void endTag(String tag, Editable output, XMLReader xmlReader) { stopIndex = output.length(); String content = output.subSequence(startIndex, stopIndex).toString();//获取点击内容 output.setSpan(new CustomClickableSpan(CUSTOM_TAG, content), startIndex, stopIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); Log.e("clickText ", content); } } //绘制图片 class URLDrawable extends BitmapDrawable { public Bitmap bitmap; @Override public void draw(Canvas canvas) { super.draw(canvas); if (bitmap != null) { canvas.drawBitmap(bitmap, 0, 0, getPaint()); } } } //处理图片 Html.ImageGetter mImageGetter = new Html.ImageGetter() { private URLDrawable urlDrawable = new URLDrawable(); //加载网络图片 @Override public Drawable getDrawable(String source) { Picasso.with(mContext).load(source).into(new Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { urlDrawable.bitmap = bitmap; urlDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight()); //不加这个图片加载不上来,不知道什么原因 tv_html.setText(tv_html.getText()); } @Override public void onBitmapFailed(Drawable errorDrawable) { } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { } }); return urlDrawable; } // 加载本地图片 // @Override // public Drawable getDrawable(final String source) { // int id = Integer.parseInt(source); // Drawable drawable = mContext.getResources().getDrawable(id); // drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable // .getIntrinsicHeight()); // return drawable; // } };

来看下效果图
Android TextView显示表情、标签、超链接_第2张图片

你可能感兴趣的:(Android TextView显示表情、标签、超链接)