在开发过程中有的时候需要加载一些标签或者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;
}
}