0

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.

shawn_wx
  • 133
  • 1
  • 11

1 Answers1

2

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
  }
plamenko
  • 1,068
  • 1
  • 8
  • 10
  • Btw, Drawee already provides FadeDrawable, so that you don't need to mess with measuring time and calculating alpha on your own. – plamenko Jan 27 '16 at 17:14
  • Also, in order to wait with crossfading until the new image actually gets loaded, you can set a controller listener and do `mFadeDrawable.fadeToLayer(mCurrentIndex)` in `onFinalImageSet`. – plamenko Jan 27 '16 at 17:53
  • thanks for reply. It's a good hint to use FadeDrawable. It works great now. – shawn_wx Jan 30 '16 at 02:13
  • Can you share the full class with us? – Arda Kara Nov 24 '16 at 17:36