8
votes

In my app, I have an Activity launching another Activity with a Fragment in it, that contains a ViewPager of images. What I have working currently, is the enter transition where the first Activity launches the second and the transition is correct. This works because, in my ViewPager I put a OnPreDrawListener on it and only resume the activity transition when the image in the pager is loaded. It looks like this:

public class ImagePagerAdapter extends PagerAdapter {
  // Constructor and other things..

  @Override
  public Object instantiateItem(ViewGroup container, final int position) {
    ImageView imageView;
    if (position == 0) {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // Shared element is the first one.
        ViewCompat.setTransitionName(imageView, "sharedImage");
      }
    }
    imageView = new ImageView(activity);

    // Just a reusable static Helper class.
    HelperPicasso.loadImage(images.get(position), imageView, false, new Callback() {
      @Override
      public void onSuccess() {
        imageView.getViewTreeObserver()
          .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
              imageView.getViewTreeObserver()
                .removeOnPreDrawListener(this);
              // When the ImageView is ready to be drawn, we can continue our activity/fragment's postponed transition animation.
              // Why? Because we want have the first image be the shared element, and we can only set it after instantiation.
              ActivityCompat.startPostponedEnterTransition(activity);
              return true;
            }
          });
      }

      @Override
      public void onError() {
        ActivityCompat.startPostponedEnterTransition(activity);
      }
    });    
  }
}

Aside from the ImageView, I also have a FrameLayout which is a shared element as well, but I mark it with it's transition name in the onCreateView of the fragment.

With this the enter transition works well for me. However, when I press the back button, the FrameLayout's exit transitions works correctly, but the ViewPager image goes blank.

My guess is that the fragment's lifecycle causes the ViewPager (and it's child views) to be destroyed during the exit transition.

I've tried adding ActivityCompat.finishAfterTransition(this) in the onBackPressed callback for the parent Activity, but it doesn't seem to have any effect.

1
Well... you came across a very complicated problem of restoring properly an exit transition that started from recyclable view. Guidelines on how to do it: android.jlelse.eu/…R. Zagórski
This wasn't a chosen design. An ImageViewPager is just one part of the of the screen. I also don't believe this is an overly complicated design i.e. imagine a e-commerce app with a ViewPager of images with TextViews, etc. below.jonalmeida
can you share your activity and fragment class ?Abdul Wahab

1 Answers

0
votes

When you have a ViewPager in the middle of a transition then you have to do some extra work in order to have a fluid and "beautiful" transition. You must play with postponeTransition() and startPostponedTransition() in order to play the transitions only when fragments or images finished to load. (It seems that you are already doing it). I recommend you to you to check the next blog: Shared Element Transitions - Part 4: RecyclerView

The target of that article is more RecyclerView + ViewAdapter + Fragments transitions but I´m sure you can adapt it in your scenario. Hope it helps.