Android TextView处理html的图片和<a>标签事件

2020-06-16 09:46:24 浏览数 (1)

话外题

最近,疫情原因搞得人心惶惶的,希望大家注意身体防止感冒,保持干净。

Android TextView处理富文本的图片和链接

贴代码
  • 布局:(需要将autoLink设置成all) autoLink的属性使用详解
代码语言:javascript复制
    <TextView
        android:id="@ id/text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:lineSpacingExtra="@dimen/dp_4"
        android:layout_margin="15dp"
        android:autoLink="all"/>
  • 解析Html
代码语言:javascript复制
/**
   * 利用urlSpan 去解析<a><a/>内容
   */
  private void setLinkClickable(final SpannableStringBuilder clickableHtmlBuilder,
      final URLSpan urlSpan) {
    int start = clickableHtmlBuilder.getSpanStart(urlSpan);
    int end = clickableHtmlBuilder.getSpanEnd(urlSpan);
    int flags = clickableHtmlBuilder.getSpanFlags(urlSpan);
    ClickableSpan clickableSpan = new ClickableSpan() {

      @Override
      public void onClick(View view) {
        //String url = urlSpan.getURL();
        //Toast.makeText(MainActivity.this, url, Toast.LENGTH_SHORT).show();
        openPage();
      }

      @Override
      public void updateDrawState(TextPaint ds) {
        ds.setUnderlineText(false);
        ds.setColor(Color.parseColor("#00ce88"));
      }
    };
    clickableHtmlBuilder.setSpan(clickableSpan, start, end, flags);
  }

  /**
   * 返回处理好的文本
   */
  private CharSequence getClickableHtml(String html) {
    Spanned spannedHtml = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY,
        new DetailImageGetter(getApplicationContext(), textView), null);//Html.fromHtml(html);
    SpannableStringBuilder clickableHtmlBuilder = new SpannableStringBuilder(spannedHtml);
    URLSpan[] urls = clickableHtmlBuilder.getSpans(0, spannedHtml.length(), URLSpan.class);
    for (final URLSpan span : urls) {
      setLinkClickable(clickableHtmlBuilder, span);
    }
    return clickableHtmlBuilder;
  }
  • 解析html的<img>标签,这边图片下载是采用glide库"com.github.bumptech.glide:glide:4.8.0"
代码语言:javascript复制
package com.fun.ex.app;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Html;
import android.util.Log;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.fun.ex.app.util.ScreenUtils;

public class ImageGetter implements Html.ImageGetter {
  private Context context;
  private TextView textView;

  ImageGetter(Context context, TextView textView) {
    this.context = context;
    this.textView = textView;
  }

  @Override
  public Drawable getDrawable(String source) {
    RequestOptions requestOptions = new RequestOptions();
    requestOptions.override(ScreenUtils.getScreenWidth(context), ScreenUtils.dip2px(context, 110));
    requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL);
    final UrlDrawable drawable = new UrlDrawable();
    Glide.with(context)
        .asBitmap()
        .load(source)
        .into(new SimpleTarget<Bitmap>() {
          @Override
          public void onResourceReady(@NonNull Bitmap resource,
              @Nullable Transition<? super Bitmap> transition) {
            float width = textView.getWidth();
            if (resource.getWidth() > width) {
              float scale = width / resource.getWidth();
              int afterWidth = (int) (resource.getWidth() * scale);
              int afterHeight = (int) (resource.getHeight() * scale);
              drawable.setBounds(0, 0, afterWidth, afterHeight);
              drawable.setBitmap(resizeBitmap(resource, afterWidth, afterHeight));
            } else {
              drawable.setBounds(0, 0, resource.getWidth(), resource.getHeight());
              drawable.setBitmap(resource);
            }
            textView.invalidate();
            textView.setText(textView.getText());
          }
        });
    return drawable;
  }

  private class UrlDrawable extends BitmapDrawable {
    private Bitmap bitmap;

    @Override
    public void draw(Canvas canvas) {
      super.draw(canvas);
      if (bitmap != null) {
        int i = canvas.getWidth() - bitmap.getWidth();
        canvas.drawBitmap(bitmap, i/2, 0, getPaint());
      }
    }

    void setBitmap(Bitmap bitmap) {
      this.bitmap = bitmap;
    }
  }

  /**
   * 使用Matrix将Bitmap压缩到指定大小
   * @param bitmap
   * @param w
   * @param h
   * @return
   */
  public Bitmap resizeBitmap(Bitmap bitmap, int w, int h)
  {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();

    float scaleWidth = ((float) w) / width;
    float scaleHeight = ((float) h) / height;

    Matrix matrix = new Matrix();
    matrix.postScale(scaleWidth, scaleHeight);

    return Bitmap.createBitmap(bitmap, 0, 0, ScreenUtils.getScreenWidth(context),
        ScreenUtils.dip2px(context, 110), null, true);
  }
}
  • 调用
代码语言:javascript复制
textView.setText(getClickableHtml(html));
 textView.setHighlightColor(Color.parseColor("#ffffffff")); //去掉文字点击的背景色
 textView.setMovementMethod(LinkMovementMethod.getInstance());  //<a>标签的点击生效需要添加这句

参考文献

https://gitee.com/adminfun/HTMLTextView https://blog.csdn.net/songmingzhan/article/details/84453085 https://www.jianshu.com/p/e8eab13bd9a2 https://blog.csdn.net/qq_36326992/article/details/90202779 https://www.cnblogs.com/mxgsa/archive/2012/11/15/2760256.html

0 人点赞