2016-02-28 3 views
1

Je viens de migrer vers la bibliothèque Fresco pour le chargement des images dans mon application.Fresco image chargement rappel

Je dois écouter l'image des événements de chargement, bien sûr je l'ai lu cet article dans la documentation Listening to download events

C'est exactement ce que je dois, mais .... Là quelques petites choses que je n'aime pas.

Mon but est de cacher View si elle ne parvient pas à le télécharger à partir du net.

  1. Je ne peux pas référencer SimpleDraweeView du contrôleur, même sur la méthode de rappel. J'ai besoin de cacher View, mais il semble que je ne peux pas y faire référence.

  2. Chaque fois que je dois charger une image, je dois créer un objet de contrôleur en utilisant Builder, ce qui peut causer des problèmes de performances lorsque j'utilise cette approche avec une liste d'éléments avec images.

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

je dois pouvoir faire référence au SimpleDraweeView du contrôleur, et dans l'approche de modèle MVC il semble correct si le contrôleur est au courant de vue.

S'il vous plaît suggérer le meilleur moyen d'enrichir mon objectif.

Merci.

Répondre

2

En ce qui concerne 1, peut-être que vous pouvez faire quelque chose comme ceci:

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

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

    @Nullable 
    protected View getView() { 
    return mViewReference.get(); 
    } 
} 

Puis:

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

Si vous ne possédez pas le point de vue accessible au moment de la création de l'auditeur, au lieu de vue passer via le constructeur de l'écouteur, vous pouvez ajouter une méthode setter et faire:

controllerListener.setView(holder.simpleDraweeViewImage); 
controller = ... 
holder.simpleDraweeViewImage.setController(controller); 

Si cela vous semble moche , bien, c'est parce que c'est moche :) Le design qui implique des références circulaires est juste moche. DraweeController n'a pas de référence à la vue (pas directement au moins). DraweeController fait référence à DraweeHierarchy qui référence les Drawables et le drawable de niveau supérieur à WeakReference dans la vue parent afin de propager les événements Drawable.Callback. Mais c'est tout. DraweeController n'a pas besoin d'affichage et nous ne pouvons pas/ne conserverons pas de référence à la vue qui s'y trouve. La raison en est que DraweeControllers et DraweeHierarchies peuvent être utilisés dans des contextes autres que View et qu'il n'est pas nécessaire que le contrôleur ait une référence arrière à la vue. DraweeController contrôle DraweeHierarchy, pas la vue.

En ce qui concerne 2, lors de la construction du contrôleur, vous pouvez spécifier setOldController(view.getController()). De cette façon, l'ancien contrôleur que vous remplacez sera réutilisé lors de la construction d'un nouveau. Cela économise des allocations et aide le défilement.

1

peut se cacher sur la méthode 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);