感谢@Budius所做的一切努力。
我的应用程序的大部分图像工作都可以由Picasso / Glide处理,但是,一些图像显示在TextView
Html.fromHtml
之内。 TextView
中的图像也经常使用。
但是,我不知道如何使用Picasso / Glide为传递给getDrawable()
的{{1}}实施ImageGetter
方法。是否可以在Html.fromHtml
和其他位图中为这些图片共享Picasso / Glide的相同缓存?
或者我应该使用自定义TextView
来分别从LruCache
缓存这些图片吗?这样会增加OOM错误的风险吗?我认为使用2个不同的系统处理图像会产生不必要的工作量。
更新:我尝试使用Picasso的ImageGetter
,但是文档说
.get()
因此在这种情况下不使用缓存。
更新
@Budius的答案是正确的,但是/**
* The result of this operation is not cached in memory because the underlying
* {@link Cache} implementation is not guaranteed to be thread-safe.
*/
的设置边界的代码丢失,这使得Drawable
没有显示在Drawable
中。所以我将TextView
类中的代码修改为:
DrawableWrapper
更新:,问题仍未解决。如果您实施前面提到的解决方案,public void setWrappedDrawable(Drawable drawable) {
if (mDrawable != null) {
mDrawable.setCallback(null);
}
mDrawable = drawable;
if (drawable != null) {
mDrawable.setBounds(0,0,mDrawable.getIntrinsicWidth(),mDrawable.getIntrinsicHeight());
drawable.setCallback(this);
}
}
中的图像会有一些奇怪的行为。有时图像无法刷新,除非您切换到另一个应用程序并切换回来,并且图像的位置严重不正确。
更新:我已经发布了以下所有测试代码。还有一些错误。如果没有占位符,它仍会抛出NPE。使用占位符,行为非常奇怪。我第一次输入TextView
时,会显示占位符,但不会更改为下载的图片。但是在我切换到另一个应用程序或按下后退按钮并再次输入TestActivity
后,会显示图片(可能是因为它在缓存中?)。
而且pic的大小也是正确的,但这个地方仍然没有留给图像。如果我拨打TestActivity
而不是mDrawable.setBounds(getBounds());
,则不会显示。
mDrawable.setBounds(0,0,getIntrinsicWidth(),getIntrinsicHeight());
public class DrawableWrapper extends Drawable implements Drawable.Callback {
private Drawable mDrawable;
public DrawableWrapper(Drawable drawable) {
setWrappedDrawable(drawable);
}
@Override
public void draw(Canvas canvas) {
mDrawable.draw(canvas);
}
@Override
public int getIntrinsicWidth() {
return 384;
}
@Override
public int getIntrinsicHeight() {
return 216;
}
//... other delegation methods are omitted
public void setWrappedDrawable(Drawable drawable) {
if (mDrawable != null) {
mDrawable.setCallback(null);
}
mDrawable = drawable;
if (drawable != null) {
mDrawable.setBounds(0,0,getIntrinsicWidth(),getIntrinsicHeight());
drawable.setCallback(this);
}
}
}
public class PicassoTargetDrawable extends DrawableWrapper
implements Target {
private Context context;
public PicassoTargetDrawable(Context context) {
super(new ColorDrawable(0));
// use application context to not leak activity
this.context = context.getApplicationContext();
}
public void onBitmapFailed(Drawable errorDrawable) {
setWrappedDrawable(errorDrawable);
invalidateSelf();
}
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
setWrappedDrawable(new BitmapDrawable(context.getResources(), bitmap));
context = null;
invalidateSelf();
}
public void onPrepareLoad(Drawable placeHolderDrawable) {
setWrappedDrawable(placeHolderDrawable);
invalidateSelf();
}
}
答案 0 :(得分:0)
我的建议是返回一个wrap drawable。并继续使用Picasso下载图像。
在以下链接中,您可以找到一个DrawableWrapper,它来自Googles支持库,但它不是公共文档的一部分,所以我只是将整个代码复制到您的项目中{{3 }}
然后你从中创建一个PicassoTargetDrawable
。
public class PicassoTargetDrawable extends DrawableWrapper
implements Picasso.Target {
private Context context;
public PicassoTargetDrawable(Context context) {
super(new ColorDrawable(0));
// use application context to not leak activity
this.context = context.getApplicationContext();
}
public void onBitmapFailed(Drawable errorDrawable) {
setWrappedDrawable(errorDrawable);
invalidateSelf();
}
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
setWrappedDrawable(new BitmapDrawable(context.getResources(), bitmap));
context = null;
invalidateSelf();
}
public void onPrepareLoad(Drawable placeHolderDrawable) {
setWrappedDrawable(placeHolderDrawable);
invalidateSelf();
}
}
然后只是加载它的问题
public void Drawable getDrawable(String source) {
PicassoTargetDrawable d = new PicassoTargetDrawable(context);
Picasso.with(context)
.load(source)
..... add here onError and placeholder drawables
.into(d);
return d;
}
<强> PS:强> 我写了所有这些而没有太多查询,可能会有一些拼写错误和一些问题需要解决,但这对你理解这个概念来说已经足够了。
<强>更新强> 只是纠正你的代码。
TextView已经告诉WrapDrawable应该使用的Bounds。如果您告诉新的mDrawable它可以使用它想要的任何大小,它将使用它想要的任何大小。因此,不应传递其自身的固有宽度/高度,而应传递给予WrapDrawable的大小
public void setWrappedDrawable(Drawable drawable) {
if (mDrawable != null) {
mDrawable.setCallback(null);
}
mDrawable = drawable;
if (drawable != null) {
mDrawable.setBounds(getBounds());
drawable.setCallback(this);
}
}