Estoy usando Picasso para descargar imágenes para mi aplicación.
Estoy en una situación en la que necesito acceder al Bitmap
primero antes de que se cargue en ImageView
. La presencia de la Downloader.Response
clase parece sugerir que esto es posible, pero no puedo encontrar ningún ejemplo de uso. No quiero escribir mucho más código para manejar de forma asincrónica este caso particular si es posible hacerlo con Picasso.
¿Alguien puede mostrarme cómo hacerlo?
Respuestas:
Encontré la respuesta en github en caso de que alguien se lo pregunte:
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(); }
La publicación recomienda no usar una devolución de llamada anónima y, en su lugar, usar una variable de instancia para el objetivo.
fuente
Target
en una vista o en un objeto de titular de vista directamente. Si no está haciendo esto, debe mantener una fuerte referencia a la instancia en algún lugar, de lo contrario, se recolectará la basura.ListView
, sugieres hacer algo comoprivate static ViewHolder { private ImageView imageView; private Target target = new Target() { public void onBitmapLoaded() { // do animation on imageView } } }
:?tomado de aquí :
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); } });
Actualizado (4 de mayo de 2016):
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) { } });
Actualizado (22 de noviembre de 2016)
o usando una referencia fuerte para
Target
que no se recolecte basuraTarget 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?) { } }
fuente
Qué puede ser más fácil que el siguiente:
val url: String = "https://...." val bitmap: Bitmap = Picasso.with(context).load(url).get()
¡Debería ser llamado no desde el hilo principal!
o con 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) } }
Recuperar mapa de bits:
getBitmapSingle(Picasso.with(context), "https:/...") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ bitmap -> // val drawable = BitmapDrawable(context, bitmap) }, Throwable::printStackTrace)
Usé Picasso v.2.5.2
fuente
Pensé que tal vez a algunos de ustedes les gustaría una versión RxJava de la respuesta anterior ... Aquí está:
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); } }); }
PD Al suscribirse, almacene la referencia de suscripción en su actividad; de lo contrario, el objetivo será GC antes de recibir una respuesta ...
fuente