@Budius の尽力に感謝します。
私のアプリの画像処理の大部分は Picasso/Glide で処理できますが、一部の画像は by で表示さTextView
れHtml.fromHtml
ます。また、 の画像TextView
も頻繁に使用されます。
ただし、渡された togetDrawable()
に対して Picasso/Glide でメソッドを実装する方法がわかりません。これらの画像と他のビットマップの Picasso/Glide の同じキャッシュを共有することは可能ですか?ImageGetter
Html.fromHtml
TextView
または、代わりにカスタムを使用して、これらの画像フォームを個別LruCache
にキャッシュする必要がありますか? ImageGetter
この方法は、OOM エラーのリスクを高めますか? また、画像を処理するために 2 つの異なるシステムを使用することは、不要な作業負荷を生み出すと思います。
更新:ピカソを使用しようとしまし.get()
たが、ドキュメントには次のように書かれています
/**
* The result of this operation is not cached in memory because the underlying
* {@link Cache} implementation is not guaranteed to be thread-safe.
*/
したがって、この場合、キャッシュは使用されません。
更新:
@Budius の答えは正しいですが、 の境界を設定するコード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);
}
}
更新:、問題はまだ解決されていません。前述のソリューションを実装すると、 の画像に奇妙な動作が発生しTextView
ます。別のアプリに切り替えて元に戻さない限り、画像を更新できず、画像の位置が大幅に間違っている場合があります。
更新:以下のテスト用のすべてのコードを投稿しました。まだいくつかのバグがあります。プレースホルダーがなくても、NPE がスローされます。プレースホルダーを使用すると、動作が非常に奇妙になります。初めて入力するTestActivity
と、プレースホルダーが表示されますが、ダウンロードした写真に変わりません。しかし、別のアプリに切り替えるか、戻るボタンを押してTestActivity
もう一度入力すると、写真が表示されます(キャッシュにあるためですか?)。
また、写真のサイズは正しいですが、画像の場所はまだ残っていません。mDrawable.setBounds(getBounds());
の代わりに呼び出すとmDrawable.setBounds(0,0,getIntrinsicWidth(),getIntrinsicHeight());
、表示されません。
DrawableWrapper
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);
}
}
}
PicassoTargetDrawable
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();
}
}
テスト活動
public class TestActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView = new TextView(this);
textView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
setContentView(textView);
String html = "<div>test<br/>" +
"<img src=\"http://i2.cdn.turner.com/money/dam/assets/150910165544-elon-evo-open-still-384x216.png\"></img>" +
"<br/>/test</div>";
textView.setText(Html.fromHtml(html, new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
PicassoTargetDrawable d = new PicassoTargetDrawable(TestActivity.this);
Picasso.with(TestActivity.this)
.load(source)
//add placeholder here
.into(d);
return d;
}
}, null));
}
}