Hello, how are you guys saving and restoring the t...
# compose
a
Hello, how are you guys saving and restoring the text states for your
TextFields
?
l
rememberSaveable
is what you’re looking for? https://developer.android.com/jetpack/compose/state#restore-ui-state
a
That’s one option, but is it what you are using? I am using MVVM so our state is in the VM
blob thinking fast 2
☝🏽 1
g
If you save state in VM, what is problem in this case? You use state from VM, user changed it, it updated state on VM, now on VM restoration it’s already there, no need to use rememberSaveable
a
VM state just survives configuration changes, it doesn’t really persist the state. For example, a user lost all their input when they got a phone call suddenly. I wonder if most people here just consider that as good enough, and if you guys are actually saving all the input states in
savedStateHandle
, Similar when we used to just save everything manually with
onSaveInstanceState
during MVP era We enable “Don’t keep activities” to detect such issues easily, do we have a bunch of tickets related to this.
c
I haven't done this before, but does savedStateHandle in a VM with hilt allow you to put stuff inside of it? https://developer.android.com/training/dependency-injection/hilt-jetpack#viewmodels
👌 1
blob thinking fast 1
m
Just create a stateFlow that updates the savedStateHandle. Create that StateFlow from that same savedState (default if empty)
a
JCRQ: do you do this in general for your VM states? We had an idea to make the VM state Parcelable to write it to the handle. Curious how you’re doing it
g
No need to to make VM parcelable, use SaveStateHandle as JCRQ suggested
m
I wrote a wrapper around StateFlow that would intercept reads and save them to SavedStateHandle while also filling in the initial value . But i think SavedStateHandle support flows now.
It depends on the use-case. Sometimes i persist the StateFlow values, sometimes not
a
Ok, but you’d had to define the keys manually, like the old way with
onSaveInstanceState
, right? You wouldn’t want to restore all your states, just some of it like text input
I just use IcePick before, but can’t find an equivalent for
savedStateHandle
m
correct, i define keys. Most of the times, you don’t need to persist the whole state, just some key parts
👍 1
a
Yeah, we have a lot of form screens with lots of inputs though. But that now gave me an idea to wrap the form input states in a class that we could easily persist to savedStateHnadle.
m
Yeah. Identify the parts of the data you want to save, group them in a data class or sth and use Parcelize. There are a lot of options, chose the best for your case
Or you can individually save them in SavedStateHandle. It would depend on how many fields there are i guess
a
Thank you! Above points from all your help confirmed our assumptions. We also considered persisting in Room or DataStore or a remote service but above should satisfy the requirements for now
h
To add to the conversation, make sure that TextField state is always backed with a Snapshot aware state holder like
mutableStateOf
. If the source of TextField state is a StateFlow, you might experience bugs due to synchronization problems between Snapshot system and the source. This ideally shouldn't affect how you save and restore your state.
a
Ok, VM
StateFlow
with
collectAsState
should be good enough, right?
a
By using StateFlow and adding async behaviours you could experience lags and errors in your TextField if it gets out of sync with the tight read-edit-write loop that happens inside the component (more or less what the tweet above tried to explain)
maybe prefer to save your state using mutableStateOf() , and rememberSaveable the state which helps with process death as suggested above
r
FWIW, I have a
TextField
in a settings screen whose value is declared locally as
rememberSaveable { mutableStateOf(...) }
and is saved to a Preferences DataStore (within a coroutine) in the
KeyboardActions
onDone
callback.
m
In order for text to work you have to feed the lambda textfieldvalue into the source. You only observe the changes, you cant chain async behavior from the viewmodel to it
i
a
Cool! I’ll check it out. So far we’ve ended up with combining
setSavedStateProvider
which triggers the provider , then put the parcelable in a bundle.
281 Views