Android Picasso:如何将已加载低清图设为高清图加载占位符
这个需求太常见了,我之前做图片列表预览的时候也碰到过一模一样的问题!你连续调用两次Picasso加载方法之所以会出现空白,是因为Picasso的核心机制:如果同一个ImageView有新的加载请求进来,会直接取消之前未完成的请求——哪怕你的低清图已经在缓存里,也可能因为内部异步处理的时序问题,还没来得及显示就被高清图的请求打断了,所以ImageView就一直空着等高清图加载完成。
下面给你两个靠谱的解决方案:
方法1:用Target确保低清图显示后再加载高清图
这是最稳妥的方式,我们可以在低清图成功从缓存加载后,再发起高清图的请求,完全避免请求被打断的问题:
Picasso.get() .load(url_small_quality) .into(new Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { // 低清图已从缓存加载完成(会立即回调),先设置到ImageView imageView.setImageBitmap(bitmap); // 现在加载高清图,加载完成后会自动替换ImageView中的低清图 Picasso.get() .load(url_full_quality) .into(imageView); } @Override public void onBitmapFailed(Exception e, Drawable errorDrawable) { // 理论上不会触发(因为低清图已经缓存),保险起见直接加载高清图 Picasso.get().load(url_full_quality).into(imageView); } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { // 可选:设置本地占位符(比如加载中图标),以防缓存意外丢失 imageView.setImageDrawable(placeHolderDrawable); } });
方法2:同步获取缓存中的低清图(注意子线程)
因为低清图已经在缓存里,我们可以同步获取它的Bitmap,设置到ImageView后再加载高清图。注意get()方法是同步操作,必须放在子线程执行:
new Thread(() -> { try { // 从Picasso缓存中同步获取低清图Bitmap Bitmap smallBitmap = Picasso.get().load(url_small_quality).get(); runOnUiThread(() -> { imageView.setImageBitmap(smallBitmap); // 加载高清图 Picasso.get().load(url_full_quality).into(imageView); }); } catch (IOException e) { e.printStackTrace(); // 缓存获取失败,直接加载高清图 runOnUiThread(() -> Picasso.get().load(url_full_quality).into(imageView)); } }).start();
内容的提问来源于stack exchange,提问作者user3566569




