我正在使用Picasso在我的应用程序中下载图像。
我处于一种需要在ImageView
加载位图之前先访问Bitmap
的情况下。 Downloader.Response
类的存在似乎表明这是可能的,但我找不到任何使用示例。如果可以使用Picasso完成此特定情况,我就不想编写大量其他代码来异步处理它。
有人能展示给我如何做吗?
如果有人想知道,我在 Github 上找到了答案:
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();
}
该文章建议不要使用匿名回调函数,而是使用实例变量来代替目标。
Target
接口。如果您没有这样做,您需要在某个地方维护该实例的强引用,否则它将被垃圾回收。 - Jake WhartonListView
的每个项目上应用自定义动画,您建议做类似这样的事情:private static ViewHolder {
private ImageView imageView;
private Target target = new Target() {
public void onBitmapLoaded() { // 在 imageView 上执行动画 }
}
}
- mbmcPicassoDrawable
完成的漂亮的alpha动画。我想保留这种行为,并同时获取位图,以添加一个由Palette
API生成的颜色叠加层。有什么办法可以做到这一点吗? - mbonnin摘自此处:
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);
}
});
更新(2016年5月4日):
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) {
}
});
更新日期(2016年11月22日)
或者对Target
使用强引用,以防它被垃圾收集器回收。
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) {
}
};
void foo() {
Picasso.with(getContext()).load(getUrl()).into(target);
}
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?) {
}
}
还有什么比这更容易的呢:
val url: String = "https://...."
val bitmap: Bitmap = Picasso.with(context).load(url).get()
应该在非主线程调用!
或者使用 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)
}
}
获取位图:
getBitmapSingle(Picasso.with(context), "https:/...")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ bitmap ->
// val drawable = BitmapDrawable(context, bitmap)
}, Throwable::printStackTrace)
我使用的是Picasso v.2.5.2
我想有些人可能需要以上答案的RxJava版本...在这里:
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);
}
});
}
P.S. 订阅时,请在您的活动中存储订阅参考,否则,在您收到响应之前,目标对象将被GC'd(垃圾回收)...