Search code examples
androidandroid-fragmentsgridviewshared-element-transition

Android shared element transition on returning to Fragment with ScrollView


I have a GridView wrapped inside of a ScrollView inside the let's call Fragment A and some CardViews inside that GridView. I know GridViews are scrollable but I expanded the height of the GridView to it's content's height because I want the elements inside the GridView and the layout above that, both scroll together. I'm well aware of that this is not the correct way of using GridView but I have my own reasons to do this so ignore that.

Anyway the problem is that shared element (the CardView) transition works well on going from fragment A to fragment B but not when coming back from fragment B to fragment A with pressing back button or with fragmentManager.popBackStack();

I set the transitionName value of CardViews programmatically with unique values for each CardView in the adapter that I'v used it for Gridview and pass it to the Fragment B with bundle arguments on CardView's onClick method. Then in the onCreateView method of Fragment B I set that same value to the CardView inside it too.

Here's the code I used it to switch to Fragment B:

Fragment fragment = new FragmentB()
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            // Defines enter transition only for shared element
            Transition changeBoundsTransition = TransitionInflater.from(mContext).inflateTransition(android.R.transition.move);
            fragment.setSharedElementEnterTransition(changeBoundsTransition);
            bundle.putString("transitionName", "card" + p.getId());
            fragment.setArguments(bundle);
            fragmentManager.beginTransaction()
                    .replace(R.id.main_container_wrapper, fragment)
                    .addToBackStack("package_root")
                    .addSharedElement(cv, "card" + p.getId())
                    .commit();

        }

And here's the onCreateView method of FragmentB:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        String transitionName = getArguments().getString("transitionName");
        view.findViewById(R.id.cv_selected_package_card).setTransitionName(transitionName);
}

As I said above the shared element transition works well on going to the FragmentB but not when coming back from it.

What I think is happening is that the FragmentA gets reloaded on coming back from FragmentB and that's why the scroll state when leaving it and when coming back to it doesn't stay the same and it displays from top. But Scroll can't be the main problem here because even when I select the first CardView at the top without scrolling down, the share element transition doesn't work on navigating back.

The target API version is 25, build API version is 25 and I test the app on a virtual device android API level 25.

So any idea how can I solve this issue.


Solution

  • The problem was the replace() method I was using to switch to the next fragment. This would destroy the fragment and remove it from fragment manager and add it back when needed again. So in order to prevent that from happening, I used the add() method to add the next fragment and hide() to hide the current one.

    Here's the code:

    Fragment currentFragment = fragmentManager.findFragmentById(R.id.main_container_wrapper);
    fragmentManager.beginTransaction()
                   .hide(currentFragment)
                    .add(R.id.main_container_wrapper, fragment)
                    .addToBackStack(null)
                    .addSharedElement(cv, "card" + p.getId())
                    .commit();