Fresco 图片加载回调

CRO*_*OSP 5 performance android callback android-image fresco

我刚刚迁移到Fresco库以在我的应用程序中加载图像。

我需要收听Image Loading Events,当然我在文档Listing to download events中阅读了这篇文章

这正是我所需要的,但是......我不喜欢的东西很少。

我的目标是隐藏,View如果它无法从网上下载它。

  1. 我不能SimpleDraweeView从控制器引用,即使是回调方法。我需要隐藏View,但似乎我无法参考它。

  2. 每次我需要加载图像时,我都需要使用 来创建控制器的对象Builder,这可能会导致在将这种方法与包含图像的大量项目列表一起使用时出现性能问题。

holder.simpleDraweeViewImage.setController(Fresco.newDraweeControllerBuilder() .setControllerListener(controllerListener) .setUri(currentItem.getImage()) .build());

我需要能够引用SimpleDraweeViewfrom 控制器,并且在MVC模式方法中,如果控制器知道视图似乎没问题。

请建议实现我的目标的最佳方式。

谢谢。

小智 8

可以隐藏 onFailure 方法:

ControllerListener listener = new BaseControllerListener<ImageInfo>() {

                @Override
                public void onFinalImageSet(String id, @Nullable ImageInfo imageInfo, @Nullable Animatable animatable) {
                   //Action on final image load
                }
                @Override
                public void onFailure(String id, Throwable throwable) {
                    //Action on failure
                }

            };
            DraweeController controller = Fresco.newDraweeControllerBuilder()
                    .setUri(uri)
                    .setControllerListener(listener)
                    .build();
            draweeView.setController(controller);
Run Code Online (Sandbox Code Playgroud)


pla*_*nko 2

关于1,也许你可以这样做:

class ControllerListenerWithView() extends BaseControllerListener {
   private final WeakReference<View> mViewReference;

   ControllerListenerWithView(View view) {
     mViewReference = new WeakReference<>(view);
   }

   @Nullable
   protected View getView() {
     return mViewReference.get();
   }
}
Run Code Online (Sandbox Code Playgroud)

然后:

ControllerListener controllerListener = new ControllerListenerWithView(holder.simpleDraweeViewImage) {
  @Override
  public void onFailure(String id, Throwable throwable) {
    View view = getView();
    if (view != null) {
      view.setVisibility(View.GONE);
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

如果在侦听器创建时无法访问视图,则可以添加一个 setter 方法并执行以下操作,而不是通过侦听器构造函数传递视图:

controllerListener.setView(holder.simpleDraweeViewImage);
controller = ...
holder.simpleDraweeViewImage.setController(controller);
Run Code Online (Sandbox Code Playgroud)

如果这对你来说看起来很丑陋,那么,那是因为它很丑陋:)涉及循环引用的设计就是丑陋的。DraweeController 没有对视图的引用(至少没有直接引用)。DraweeController 引用了一个 DraweeHierarchy,它引用了 Drawable,并且顶级的 Drawable 有一个对父视图的 WeakReference,以便传播 Drawable.Callback 事件。但仅此而已。DraweeController 不需要视图,我们不能/不会保留对其中视图的引用。原因是 DraweeControllers 和 DraweeHierarchies 可以在 View 以外的上下文中使用,并且控制器不需要具有对视图的反向引用。DraweeController 控制 DraweeHierarchy,而不是视图。

关于2,在构建控制器时,您可以指定setOldController(view.getController()). 这样,您要更换的旧控制器将在构建新控制器时被重复使用。这可以节省分配并有助于滚动性能。