Wakil Ahmad
Wakil Ahmad

Reputation: 121

Shared transition with getChildFragmentManager() not working but working with getFragmentManager()

I implement fragments as below:

  1. Activity to hold parent fragment. Uses getSupportFragmentManager() to add Parent fragment.
  2. In parent fragment I use getChildFragmentManager() and transaction to replace childFragment.
  3. In childFragment I again call childFragment and so on....
  4. Everything work fine except shared transition.'
  5. If I use getFragmentManager() instead of getChildFragmentManager() then there is shared transition but then there is not concept of getChildFragmentManager().

The code sample looks like:

/*This code does not show animation*/
getChildFragmentManager()
                .beginTransaction()
                .addSharedElement(transitionView, ViewCompat.getTransitionName(transitionView))
                .replace(R.id.fragment_container, categoryDetailChildFragment)
                .addToBackStack(TAG)
                .commit();

and the code that shows animation is:

  getFragmentManager()
                .beginTransaction()
                .addSharedElement(transitionView, ViewCompat.getTransitionName(transitionView))
                .replace(R.id.fragment_container, categoryDetailChildFragment)
                .addToBackStack(TAG)
                .commit();

Why there is no shared transition when getChildFragmentManager()? Please help anybody.

Upvotes: 9

Views: 775

Answers (2)

i_o
i_o

Reputation: 789

Watch this video from 15:00 to 17:00 Fragment tricks (Google I/O '17)

I was having the same problem. Just do this!

inside your onCreateView method:

postponeEnterTransition();
final ViewGroup group = inflater.inflate(R.layout.layout_to_inflate,container,false);

ViewTreeObserver.OnGlobalLayoutListener treeObserver = new ViewTreeObserver.OnGlobalLayoutListener(){

@Override
        public void onGlobalLayout() {
            startPostponedEnterTransition();
            group.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }    
}


group.getViewTreeObserver().addOnGlobalLayoutListener(treeObserver);

Make sure you call setReorderingAllowed(true) when you call your addSharedElement() fragment transaction call!

Try it and the animations should run smoothly. I know Android Fragments are not easy to work with!

Upvotes: 0

Rubén Viguera
Rubén Viguera

Reputation: 3584

Every fragment has their own childFragmentManager. Therefore if you have multiple nested fragments one inside another you should refer to the same fragment's childFragmentManager, the same in which you use addSharedElement().

Therefore if you have:

ActivityA
|_ FragmentB
   |_ FragmentC
      |_ FragmentD

You should use the uppest common fragment's getChildFragmentManager() -Fragment B in this case, for Fragment C and Fragment D- to ensure every nested fragment refers to the same fragmentManager. That's why it works when you use activity's fragmentManager, because there are just one activity and every one refers to the same one by using getActivity()

To get parent's Fragment in a nested fragment you could use getParentFragment() on your nested fragment's onAttach() method. You could also cast it to a certain class like FragmentB:

override fun onAttach(context: Context) {
    super.onAttach(context)

    val fragment: FragmentB = parentFragment.parentFragment.parentFragment... as FragmentB
}

Upvotes: 1

Related Questions