androidandroid-layoutandroid-transitionsactivity-transition

Android: Is there a way to do Activity Transitions if one of the shared elements is in a Fragment? Activity A Fragment to Activity B


I understand that there are Activity Transitions to make transitions for shared elements between Activity A and Activity B like so:

ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
    Pair.create(view1, "agreedName1"),
    Pair.create(view2, "agreedName2"));

There are also Fragment Transitions for Fragments that are in the same Activity. But is there a way to transition shared elements between Activity A's Fragment views and Activity B?

My Activity A has a ViewPager with Fragments that have views that I would like to transition into Activity B's views. So the Views that I want to transition into Activity B are actually in Activity A's Fragment layout, not directly in Activity A's layout.

Is there any way to make this work?


Solution

  • Yes, fragments don't cause problems with Activity Transitions on their own. The main issue is that fragments tend to load their contents at a later time and the transition system gets confused about what is available.

    When there is a transition, the Views don't actually move from one activity to another. There is a snapshot taken of the location and size (and a bitmap) and that information is transferred to Activity B. The corresponding View in Activity B then is transitioned from that location and size to the final location and size. The bitmap is normally not used, but is there in case you need it for a cross-fade or similar.

    If the shared element is in a fragment in Activity A, then the outgoing transition is fine -- the View exists and is positioned properly. The only potential problem is the returning transition. When Activity B closes, it is possible for Activity A to need to be restarted (memory pressure, orientation change, etc). In that case, the fragment will have to be recreated and the View placed properly. In onActivityReenter, call postponeEnterTransition and then when the fragment is loaded and layout has completed, call startPostponedEnterTransition. Then Activity B will know what the final position and size of the shared element will be, so it can start its animation.

    The same is true in reverse, when Activity B has a shared element in a fragment. You'll have to postpone the enter transition in onCreate until after the fragment is loaded and layout is complete in Activity B.