One Off the Slack: How Do We Remember Across Configuration Changes?

Rick Regan asked:

I want to remember scroll state across configuration changes within a Text with modifier .verticalScroll(scrollState).

I have a fixed height Text that I’ve scrolled down into. When I rotate, the text is still there and in its proper scroll position when I use the third option.

When Google’s Ian Lake pointed out that rememberScrollState() uses rememberSaveable(), Rick did a bit more testing, and eventually concluded:

I know what it is. I use the same element in both configurations, with logic like

if (maxWidth < 500.dp) {
  MyComposable()
} else {
  MyComposable()
}

So each one gets its own fresh ScrollState. (The text they display is in my app state.) To fix it, I have to hoist rememberScrollState. If I put it in that top-level composable then I have to pass it down through many layers of composables (not shown). That makes option 3 above (val scrollState = ScrollState(0) in my app state) more appealing. But is that bad practice?

Ian mentioned that there was a gap in the plan:

Well, option 3 won’t actually help with process death and recreation (i.e., what you test when you enable the ‘Don’t keep activties’ developer option); you really do need to save it and restore it at some level

Rick conceded that rememberSaveable() probably was the right answer, though he expressed some trepidation:

Thanks, I was overlooking process death (which is down there on my todo list 🙂). Obviously then I’ll also have to save the accompanying text with rememberSaveable. I have the text as text by mutableStateOf() in my “view model” (not actually ViewModel); so looking ahead: is rememberSaveable(text) { text } (at an appropriate-level composable) the way to do it so that it keeps updating the “save”?

Ian confirmed:

If that text hasn’t been actually persisted to disk, yep, you’ll want to use rememberSaveable


Read the original thread in the kotlinlang Slack workspace. Not a member? Join that Slack workspace here!