共享元素转换在毕加索的第一次加载时不能工作



我正在尝试使用Picasso从URL加载图像到ImageView

共享过渡的图像在RecyclerView中的CardView和第二个它只是在LinearLayout中。第一次请求时,元素没有动画,因为picasso需要将图像加载到视图中,但在随后的请求中,它很好。

在启动转换之前,我如何确保ImageView已成功填充?

解决方案是使用postponeEnterTransition()startPostponedEnterTransition()调用来确保picasso在活动开始之前完成将图像加载到视图中。

这是一个很好的关于这个的博客条目。

下面是onCreate

的示例
ActivityCompat.postponeEnterTransition(this);
Picasso.with(this.getApplicationContext())
    .load("https://goo.gl/oiyTor")
    .noFade()
    .fit()
    .centerInside()
    .error(R.drawable.user_placeholder_error)
    .into(((ImageView) findViewById(R.id.game_view_image)), new Callback() {
        @Override
        public void onSuccess() {
            ActivityCompat.startPostponedEnterTransition(targetActivity);
        }
        @Override
        public void onError() {
            ActivityCompat.startPostponedEnterTransition(targetActivity);
        }
    });

如果您想避免延迟进入过渡所造成的影响,您可以强制Picasso使用它已经在缓存中的任何内容:

Target target = new Target() {
      @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        this.imageView.setImageBitmap(bitmap);
      }
      @Override public void onBitmapFailed(Drawable errorDrawable) {}
      @Override public void onPrepareLoad(Drawable placeHolderDrawable) {}
};
Picasso.with(context)
       .load(url)
       .networkPolicy(NetworkPolicy.OFFLINE)
       .into(target);

通过传递Target实例而不是ImageView实例,您将迫使Picasso交付它为该URL缓存的任何内容。如果您传递ImageView,则不会立即加载图像。

请注意,您应该将目标对象保存在成员变量中,因为它被Picasso作为弱引用保存,所以您不希望它被垃圾收集。

你可以用Universal Image Loader代替Picasso,它可以很好地处理这个问题

DisplayImageOptions options = new DisplayImageOptions.Builder()
                .showImageOnLoading(drawable) 
                .showImageForEmptyUri(emptyDrawable) 
                .showImageOnFail(errorDrawable) 
                .resetViewBeforeLoading(false)  
                .cacheInMemory(true) 
                .cacheOnDisk(true) 
                .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
                .build();
        imageLoader.displayImage(url, iv, options);