Używam Picassa do pobierania obrazów do mojej aplikacji.
Jestem w sytuacji, w której muszę uzyskać dostęp do Bitmap
pierwszego, zanim zostanie załadowany do ImageView
. Obecność Downloader.Response
klasy wydaje się sugerować, że jest to możliwe, ale nie mogę znaleźć żadnych przykładów użycia. Nie chcę pisać więcej kodu, aby asynchronicznie obsłużyć ten jeden konkretny przypadek, jeśli można to zrobić z Picassem.
Czy ktoś może mi pokazać, jak to zrobić?
Odpowiedzi:
Znalazłem odpowiedź na githubie na wypadek, gdyby ktoś się zastanawiał:
private Target target = new Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { } @Override public void onBitmapFailed(Drawable errorDrawable) { } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { } } private void someMethod() { Picasso.with(this).load("url").into(target); } @Override public void onDestroy() { // could be in onPause or onStop Picasso.with(this).cancelRequest(target); super.onDestroy(); }
Post zaleca, aby nie używać anonimowego wywołania zwrotnego, a zamiast tego używać zmiennej instancji dla celu.
źródło
Target
na widoku lub obiekcie posiadacza widoku. Jeśli tego nie robisz, musisz utrzymywać silne odniesienie do instancji w innym miejscu, w przeciwnym razie zostanie ona usunięta.ListView
, to proponuję zrobić coś takiego:private static ViewHolder { private ImageView imageView; private Target target = new Target() { public void onBitmapLoaded() { // do animation on imageView } } }
?wzięte stąd :
Picasso.with(this) .load(url) .into(new Target() { @Override public void onBitmapLoaded (final Bitmap bitmap, Picasso.LoadedFrom from){ /* Save the bitmap or do something with it here */ //Set it in the ImageView theView.setImageBitmap(bitmap); } });
Zaktualizowano (4 maja 2016 r.):
Picasso.with(this) .load(youUrl) .into(new Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { } @Override public void onBitmapFailed(Drawable errorDrawable) { } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { } });
Zaktualizowano (22 listopada 2016 r.)
lub używając silnego odniesienia dla,
Target
aby nie było zbierane jako śmieciTarget target = new Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { } @Override public void onBitmapFailed(Drawable errorDrawable) { } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { } }; void foo() { Picasso.with(getContext()).load(getUrl()).into(target); }
Kotlin
object: com.squareup.picasso.Target { override fun onBitmapFailed(e: java.lang.Exception?, errorDrawable: Drawable?) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun onPrepareLoad(placeHolderDrawable: Drawable?) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) { } }
źródło
Co może być łatwiejsze niż następne:
val url: String = "https://...." val bitmap: Bitmap = Picasso.with(context).load(url).get()
Powinien być wywoływany nie z głównego wątku!
lub z RxJava 2:
fun getBitmapSingle(picasso: Picasso, url: String): Single<Bitmap> = Single.create { try { if (!it.isDisposed) { val bitmap: Bitmap = picasso.load(url).get() it.onSuccess(bitmap) } } catch (e: Throwable) { it.onError(e) } }
Pobierz mapę bitową:
getBitmapSingle(Picasso.with(context), "https:/...") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ bitmap -> // val drawable = BitmapDrawable(context, bitmap) }, Throwable::printStackTrace)
Użyłem Picassa 2.5.2
źródło
Pomyślałem, że może niektórzy z was chcieliby mieć wersję RxJava powyższej odpowiedzi ... Oto ona:
public static Observable<Bitmap> loadBitmap(Picasso picasso, String imageUrl) { return Observable.create(new Observable.OnSubscribe<Bitmap>() { @Override public void call(Subscriber<? super Bitmap> subscriber) { Target target = new Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { subscriber.onNext(bitmap); subscriber.onCompleted(); } @Override public void onBitmapFailed(Drawable errorDrawable) { subscriber.onError(new Exception("failed to load " + imageUrl)); } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { } }; subscriber.add(new Subscription() { private boolean unSubscribed; @Override public void unsubscribe() { picasso.cancelRequest(target); unSubscribed = true; } @Override public boolean isUnsubscribed() { return unSubscribed; } }); picasso.load(imageUrl).into(target); } }); }
PS Podczas subskrybowania przechowuj odniesienie do subskrypcji na temat swojej aktywności, w przeciwnym razie cel zostanie GC przed otrzymaniem odpowiedzi ...
źródło