Search code examples
androidfacebookimagefresco

Fresco crossfading within a DraweeHolder


I'm using DraweeHolder in my custom view to display image. When I want to update the image with a new resource, I create a new DraweeController, then setController to the DraweeHolder.

What I'm trying to implement is the crossfading effect between the previous and new image. For fade in/out, I setAlpha to the drawable recursively.

void handleTransition(DraweeHolder draweeHolder, long startingTime) {
    Drawable drawable = draweeHolder.getTopLevelDrawable().mutate();
    int duration = 2000;
    long currTime = System.currentTimeMillis();
    int diff = (int) (currTime - startingTime);
    int toAlpha = Math.max(0, 255 - (255 * diff / duration));
    drawable.setAlpha(toAlpha);
    invalidate();
}


@Override
protected void onDraw(Canvas canvas) {
    Log.d(TAG, "onDraw()");
    super.onDraw(canvas);
    synchronized (this) {
        handleTransition(draweeHolder, mCurrentTransStartTime);
    }
}

It seems working fine, except that onDraw will be called too many times. However, I have no idea how can we have two images appear at the same time (crossfade) in this DraweeHolder. Even setting high/low resolution image for DraweeHolder doesn't give the option of crossfading.


Solution

  • You are on the right track. You will have to write a custom view (e.g. by extending ImageView). Keep in mind that you need to wire up some things in order for Drawee to work correctly, read here how to do that.

    You will need two DraweeHolders. When using multiple holders it's best to keep them in a MultiDraweeHolder:

      private void init() {
        mMultiDraweeHolder = new MultiDraweeHolder<GenericDraweeHierarchy>();
        // holders for the two images to cross-fade between
        Drawable drawables[] = new Drawable[2];
        for (int i = 0; i < drawables.length; i++) {
          GenericDraweeHierarchy hierarchy = createDraweeHierarchy();
          mMultiDraweeHolder.add(DraweeHolder.create(hierarchy, getContext()));
          drawables[i] = hierarchy.getTopLevelDrawable();
        }
        mFadeDrawable = new FadeDrawable(drawables);
        // no need to override onDraw, ImageView superclass will correctly draw our fade drawable if we set it like this:
        super.setImageDrawable(mFadeDrawable);
        mCurrentIndex = 0;
      }
    
      void loadNextImage(DraweeController controller) {
        mCurrentIndex = (mCurrentIndex + 1) % 2;
        mMultiDraweeHolder.get(mCurrentIndex).setController(controller);
        mFadeDrawable.fadeToLayer(mCurrentIndex);
      }
    
      GenericDraweeHierarchy createDraweeHierarchy() {
        // create a new drawee hierarchy here,
        // as each image needs to have its own instance
      }