Android TextView加載標籤/HTML內容

在開發過程中有的時候需要加載一些標籤或者HTML的內容,有的是純文本,有的包含圖片,這種情況大部分人都會想到用webview來加載,但是webview比較繁瑣,我們可以用TextView來代替。
步驟一:
只需要創建一個普通的TextView就好
步驟二:
查看TextView的setText 方法我們可以發現其中有一個方式傳遞的參數是CharSequence;但是這個CharSequence是一個接口,通過查看源碼可以看見CharSequence是一個可讀的序列。
步驟三:
構造一個可以傳入CharSequence參數值,因爲我們需要加載的是標籤或者HTML 所以我們直接找到這個類,在查看代碼的過程中我們可以發現其中有一個方法是和CharSequence相關的
在這裏插入圖片描述
也許這裏並沒有直接或者說明顯的顯示和CharSequence有關,但是我們看一下這個方法的返回值Spanned,繼續查看代碼就會發現這個Spanned是繼承於CharSequence的接口,所以這個方法和CharSequence是相關聯的。OK回過頭來看看這個方法的參數,source : 需要設置的值;flags:加載時顯示方式;ImageGetter:這就很重要了 下面會有詳細介紹。TagHandler:標記
ImageGetter:這是一個Html 類的內部靜態接口,通過源碼可以看見只有一個方法是可以實現的(getDrawable)

public class UrlImageGetter implements Html.ImageGetter, Drawable.Callback {
	Context mContext;
  TextView mTextView;
  int mWidth;
  private final Set<GifViewTarget> mTargets;
  // 設置是否顯示圖片
  private boolean noImage = false;
  // 設置圖片顯示的最大高度
  private int newHeight = 0;
	/**獲取當前控件對應的tag*/
  public static UrlImageGetter get(View view) {
    return (UrlImageGetter) view.getTag(R.id.drawable_callback_tag);
  }

  public UrlImageGetter(TextView t, Context c) {
    this.mContext = c;
    this.mTextView = t;
    mWidth = c.getResources().getDisplayMetrics().widthPixels;
    mTargets = new HashSet<>();
    mTextView.setTag(R.id.drawable_callback_tag, this);
  }

  public UrlImageGetter(TextView t, Context c, boolean noImage) {
    this.mContext = c;
    this.mTextView = t;
    mWidth = c.getResources().getDisplayMetrics().widthPixels;
    mTargets = new HashSet<>();
    mTextView.setTag(R.id.drawable_callback_tag, this);
    this.noImage = noImage;
  }

  @Override
  public void invalidateDrawable(@NonNull Drawable who) {
    mTextView.invalidate();
  }

  @Override
  public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {

  }

  @Override
  public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {

  }

  private class GifViewTarget extends SimpleTarget<GifDrawable> {

    private final UrlDrawable2 mDrawable;

    private GifViewTarget(UrlDrawable2 drawable) {
      mTargets.add(this);
      this.mDrawable = drawable;
    }

    private Request request;

    @Override
    public Request getRequest() {
      return request;
    }

    @Override
    public void onResourceReady(GifDrawable resource, Transition<? super GifDrawable> transition) {
      Rect rect;
      if (resource.getIntrinsicWidth() > 100) {
        float width;
        float height;
        if (resource.getIntrinsicWidth() >= mWidth) {
          float downScale = (float) resource.getIntrinsicWidth() / mWidth;
          width = (float) resource.getIntrinsicWidth() / (float) downScale;
          height = (float) resource.getIntrinsicHeight() / (float) downScale;
        } else {
          float multiplier = (float) mWidth / resource.getIntrinsicWidth();
          width = (float) resource.getIntrinsicWidth() * (float) multiplier;
          height = (float) resource.getIntrinsicHeight() * (float) multiplier;
        }
        rect = new Rect(0, 0, Math.round(width), Math.round(height));
      } else {
        rect = new Rect(0, 0, resource.getIntrinsicWidth() * 2, resource.getIntrinsicHeight() * 2);
      }
      resource.setBounds(rect);
      mDrawable.setBounds(rect);
      mDrawable.setDrawable(resource);
      //if (resource.isRunning()) {
      mDrawable.setCallback(get(mTextView));
      resource.setLoopCount(GifDrawable.LOOP_FOREVER);
      resource.start();
      // }
      mTextView.setText(mTextView.getText());
      mTextView.invalidate();
    }

    @Override
    public void setRequest(Request request) {
      this.request = request;
    }
  }

  private boolean isGif(String path) {
    int index = path.lastIndexOf('.');
    return index > 0 && "gif".toUpperCase().equals(path.substring(index + 1).toUpperCase());
  }

  @Override
  public Drawable getDrawable(String source) {

    if (isGif(source)) {
      final UrlDrawable2 urlDrawable2 = new UrlDrawable2();

      if (newHeight != 0) {
        Glide.with(mContext)
            .asGif()
            .load(source)
            .apply(new RequestOptions().override(newHeight))
            .into(new GifViewTarget(urlDrawable2));
      } else {
        Glide.with(mContext).asGif().load(source).into(new GifViewTarget(urlDrawable2));
      }
      return urlDrawable2;
    } else {
      final UrlDrawable urlDrawable = new UrlDrawable();

      if (newHeight != 0) {
        Glide.with(mContext)
            .asBitmap()
            .load(source)
            .apply(new RequestOptions().override(newHeight))
            .into(new BitmapTartget(urlDrawable));
      } else {

        Glide.with(mContext).asBitmap().load(source).into(new BitmapTartget(urlDrawable));
      }
      return urlDrawable;
    }
  }

  @SuppressWarnings("deprecation")
  public class UrlDrawable extends BitmapDrawable {
    protected Bitmap bitmap;

    @Override
    public void draw(Canvas canvas) {
      // override the draw to facilitate refresh function later
      if (bitmap != null) {
        canvas.drawBitmap(bitmap, 0, 0, getPaint());
      }
    }
  }

  private class BitmapTartget extends SimpleTarget<Bitmap> {

    private final UrlDrawable urlDrawable;

    public BitmapTartget(UrlDrawable drawable) {
      this.urlDrawable = drawable;
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {

      urlDrawable.bitmap = resource;
      int width = 0;
      int height = 0;
      if (!noImage) {
        Activity currentActivity = AppManagerUtil.getAppManager().currentActivity();
        width = resource.getWidth();
        height = resource.getHeight();
        if (null != currentActivity) {
          int screenWidth = DisplayUtils.getScreenWidth(currentActivity);
          width = resource.getWidth() > screenWidth ? screenWidth : resource.getWidth();
          height = resource.getHeight() * width / resource.getWidth();
        }
      }
      urlDrawable.setBounds(0, 0, width, height);
      mTextView.invalidate();
      mTextView.setText(mTextView.getText());
    }
  }

  public void setNewHeight(int newHeight) {
    this.newHeight = newHeight;
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章