0

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.

add 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?

Artie Vandelay
  • 436
  • 2
  • 10

0 Answers0