Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reverse shared element transition on back

I am currently using the following code to transition a block on the right side of the screen to a shared element on the left:

 FragmentDetail newFragment = FragmentDetail.newInstance(id);

 setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.trans_move));
 setExitTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode));
 View block = view.findViewById(R.id.blocks);
 block.setTransitionName("block");

 newFragment.setSharedElementEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.trans_move));
 newFragment.setEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode));


 newFragment.setTransitionId(block.getTransitionName());
 FragmentTransaction trans = getFragmentManager().beginTransaction();
 trans.replace(R.id.container, newFragment);
 trans.addToBackStack(null);
 trans.addSharedElement(block, block.getTransitionName());
 trans.commit();

This works exactly how I want, but I would like to reverse the effect upon pressing the back button, animating the item back in. As is, the explode animation plays, but the transition does not.

Any help is greatly appreciated.

Thanks Josh

like image 746
Josh Avatar asked Feb 01 '15 13:02

Josh


3 Answers

KOTLIN with Android Navigation Component

For anyone who's here looking for the answer to this question when you're using the Android Navigation component, you can make the reverse transition animation work by adding these lines to the onViewCreated function of the starting fragment:

        postponeEnterTransition()
        view.doOnPreDraw { startPostponedEnterTransition() }

You would generally use this if you are opening the second fragment by clicking on a RecyclerView item.

like image 190
Joe Muller Avatar answered Nov 13 '22 22:11

Joe Muller


Let's say you have two fragments, A and B, and A commits a fragment transaction to start fragment B.

Then that means the exit and reenter transitions should be set on A and the enter and return transitions should be set on B.

It looks like you are calling setSharedElementReturnTransition on the calling fragment instead of the called fragment (newFragment, in this case), which might be causing the problem.

BTW, you should consider calling the set*****Transition() and setSharedElement*****Transition() methods in your fragment's onCreate() method instead of immediately before a fragment transaction is committed. If a fragment is destroyed and recreated, these transitions will be forgotten... so setting them in onCreate() is much safer.

like image 4
Alex Lockwood Avatar answered Nov 13 '22 23:11

Alex Lockwood


switch from

trans.replace(R.id.container, newFragment);

to

trans.hide(oldFragment).add(R.id.container, newFragment).show(newFragment)

and it should work (as in my case). reverting a shared fragment transition seems to only work if you hide the old one, instead of replacing it.

like image 3
Markus Schulz Avatar answered Nov 13 '22 23:11

Markus Schulz