You probably already found the answer to this question, but if you didnβt do it, hereβs what I did to fix it after a few hours of scratching my head.
The problem I'm thinking of is a combination of two factors:
Fragmnets loading of Fragmnets in ViewPager , which means that the activity returns much faster than its fragments contained within the ViewPager
If you look like me, then your child ViewPager are likely to be of the same type. This means that they all have the same transition name (if you specified them in your xml layout) , if you do not install them in the code and only install it once, on the visible fragment .
To fix both of these problems, this is what I did:
1. Fixing problems with delayed downloads:
Inside your activity (the one that contains the ViewPager ), add this line after super.onCreate() and before setContentView() :
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityCompat.postponeEnterTransition(this);
2. Fixing a problem with several fragments with the same transition name:
Now there are quite a few ways to do this, but this is what I got inside my "detailed" action, that is, the activity that contains the ViewPager (in onCreate() , but you can do it anywhere):
_viewPager.setAdapter(_sectionsPagerAdapter); _viewPager.setCurrentItem(position); ... ... _pagerAdapter.getItem(position).setTransitionName(getResources().getString(R.string.transition_contenet_topic));
You need to be careful, because Activity may not yet attach to your ViewPager fragment, so itβs easier to just pass the name of the transition from the operation to the fragment if you load it from a resource
The actual implementation is as simple as you expect:
public void setTransitionName(String transitionName) { _transitionName = transitionName; }
Then inside the onViewCreated() add this line:
public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ... if (_transitionName != null && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { setTransitionNameLollipop(); } ... } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void setTransitionNamesLollipop() { _imgTopic.setTransitionName(_transitionName); }
The final piece of the puzzle is to find out when your piece is fully loaded, and then call ActivityCompat.startPostponedEnterTransition(getActivity()); .
In my case, my fragments were not fully loaded until I load most of the things from the UI thread, which means that I needed to figure out a way to call this when everything was loaded, but if that is not your thing, you can call this right after calling setTransitionNameLollipop() .
The problem with this approach is that the transition to the output may not work if you are not very careful and reset the name of the transition to the "visible" fragment right in front of you exit activity to go back. This can be done as follows:
- Listen to page changes on
ViewPager - Remove the transition names (names) as soon as your fragment is not displayed.
- Set the transition name to the visible fragment.
- Instead of calling
finish() call ActivityCompat.finishAfterTransition(activity);
This can become very difficult very soon if you need a transition to go to the RecyclerView , which was my business. For this, there is a much better answer provided by @Alex Lockwood here: ViewPager snippets - Transitions with a common element that has very well written sample code (although much more complicated than what I just wrote) here: https://github.com/ alexjlockwood / activity-transitions / tree / master / app / src / main / java / com / alexjlockwood / activity / transitions
In my case, I did not have to go so far as to implement his solution, and the above solution, which I wrote for my case.
If you have several common elements, I am sure you can figure out how to extend the methods to suit them.