How to save/restore state of MotionLayout on activity rotation

1.9k Views Asked by At

Steps to reproduce: Run an activity with MotionLayout inside it Transition to a non-initial state Rotate the device or enable/disable dark mode

Observed: The MotionLayout is in it's initial state Expected: The MotionLayout is in the state that was shown before the rotation

Should I put the id of the state inside the savedInstanceState, and then transition to that state (with 0 duration, so it is instantaneous) inside onCreate? This approach I think would work but feels a bit hacky, does anyone know a better solution to this problem?

Here's a recording of the problem: enter image description here

2

There are 2 best solutions below

2
On BEST ANSWER

MotionLayout does not automatically save its state. The state of the layout can be quite complex.

The most generic way to save the basic stat of a MotionLayout is to save the bundle returned by getTransitionState() and then call setTransitionState(Bundle b) on restore

0
On

I know I come a bit late to the party, but this may help someone in the future!

I had a similar problem with the Motion layout and all solutions I found resulted in rendering problems when scrolling my motion layout again, especially for an image that disappears on scroll, so I came up with the following for a Fragment

Save the progress of the MotionLayout inside a viewModel:

@HiltViewModel
class OverviewViewModel @Inject constructor() : ViewModel() {
    ...
     var motionProgress = 0.0f
    ...
}

In the fragments onPause save the progress state of the MotionLayout:

 override fun onPause() {
    super.onPause()
    viewModel.motionProgress = motionLayout.progress
}

And in your onCreateView() method you set the progress to your layout:

    override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
     ...
     motionLayout.post{
        motionLayout.progress = viewModel.motionProgress
    }
    ...
  }

For anyone wondering, I have tried saving a local variable in onSaveInstanceState() but I had problems with this method not being called when using NavigationComponents

Hope it helps, Cheers!