I'm struggling to get the desired effect when adding a fragment to the backstack.
I have tried using ft.replace
as well as ft.add
in the following code to add my fragment, but neither give me the desired effect.
val ft = supportFragmentManager.beginTransaction()
ft.setTransition(TRANSIT_FRAGMENT_OPEN)
ft.replace(R.id.fragment_container, fragment)
ft.addToBackStack("root")
ft.commit()
First uses ft.add
, second uses ft.replace
.
The issue is that I want the state of the previous fragment to be fully restored when I go back to it using the backstack, which ft.add
does correctly.
- The toplevel RecyclerView keeps its position correctly, as well as
- the nested RecyclerView for the albums, and even
- the MotionLayout at the top showing the image of a record remembers its position.
This is to be expected, because the old fragment was never destroyed: it was always there, just behind the new fragment.
However, unlike ft.replace
, ft.add
does not animate the old fragment. It only zooms the new fragment, but I would like it to animate both, like in the right GIF. ft.replace
brings with it the problem that it only seems to remember half the state:
- the toplevel RecyclerView keeps its scrolling position, but
- the nested RecyclerView doesn't, and
- the MotionLayout at the top doesn't either.
I think this is partly to be blamed on the fact that, for some reason, when I use ft.replace
, the old fragment's onViewCreated
method gets called again when I pop the backstack. This causes the RecyclerView's adapter to be recreated and the MotionLayout's position to be reset. I tried keeping a boolean flag to prevent the onViewCreated
method from being called twice, but that just results in the RecyclerView never getting an adapter when going back.
How do I make sure the state of the old fragment is fully retained, whilst getting the nice animation as if it were being replaced?