Usually, compose codes are like
@Preview
@Composable
fun BuildMyView() {
val counter = rememberSaveable { mutableStateOf(1) }
Text(
modifier = Modifier
.fillMaxSize()
.wrapContentSize(align = Alignment.Center)
.clickable { counter.value },// click and text will
text = "${counter.value}"
)
}
Recently, I want to collect all view data together and build a state and create sth like:
data class MyState(
val data: MutableState<String>
)
val stateTemp = MyState(mutableStateOf("hello"))
@Preview
@Composable
fun BuildMyView() {
val counter = rememberSaveable { stateTemp.data}
Text(
modifier = Modifier
.fillMaxSize()
.wrapContentSize(align = Alignment.Center)
.clickable { stateTemp.data.value = "-1" },
text = counter.value
)
}
In second case, when I click text, it does but if I go to a new page and come back, all changes will lost however in first case it doesn't.
I then read some compose codes and get confusing since I didn't find where remember subscribe a mutable state.
Is there a method to make mutable state out of compose work?
Beside, is somewhere I can find codes generated by compose under my gradle build dir or anywhere else (except dex, that's too hard to read)? Compose really did amazing job but I cannot read the real codes running and that makes much more difficult for freshman to get start.
UPDATE ON 2022/6/15
Now I found a proper solution to use viewmodel instead of state holder and use mutableState in viewmodel and subscribe state in view composable part so that I can avoid complex grammar of viewmodel with livedata. Hope that will help followers.
CodePudding user response:
I then read some compose codes and get confusing since I didn't find where remember subscribe a mutable state.
As far as I understand, remember
calculates and caches what ever is inside its lambda
during the first composition
or first execution of the @composable
function only, this is the only thing that the @composable
remembers or subscribes on. Unless you provide a key
to a remember
, that when it changed, it will trigger a re-calculation
to be remembered
Is there a method to make mutable state out of compose work?
Do you mean some piece of non composable code or function that will automatically trigger when this State
object is changed? If this is what you mean, I suppose you just have to resort back to good old observable patterns
As far as I understand, compose States
are specifically designed to work with the underlying Snapshot
system where the heart of triggering the composition
mechanism happens, I can't imagine (so far) any usage of State
objects outside of composition or outside of the Snapshot
system.
In second case, when I click text, it does but if I go to a new page and come back, all changes will lost however in first case it doesn't.
As for using rememberSaveable
, I would be careful using it , it might look the same as remember
with just an additional power of saving/restoration
, but it has more power with equal responsibilities imposed to it that you have to take into account when using it. I haven't used or defined a rememberSaveable
object without defining a Saver
in it explicitly, so I can only assume in your case here
rememberSaveable { mutableStateOf(1) }
the composable
observes a rememberSaveable
that also observes an actual object that actually changes
and implicitly saves and restores that object with the most recent value
while in this, I think
data class MyState(
val data: MutableState<String>
)
val stateTemp = MyState(mutableStateOf("hello"))
...
...
rememberSaveable { stateTemp.data}
rememberSaveable
saves the state of the val data: MutableState<String>
(which is empty), while the composable
observes an instance of a mutableState
that is changing, unfortunately rememberSaveable
already saved an initial state in way like this rememberSaveable { data: MutableState<String> }
not the actual mutableStateOf("hello")
that changes, so it will restore it that way when you go back.
I'm curious, you can try implementing your MyState class with a companion object holding a Saver
where you can define how rememberSaveable
will Save
and Restore
the data, I think it will restore it when you navigate back to that screen. When you debug a Saver
implementation, you will also notice that the restoration
is invoked during recomposition. Im not quite sure though
Disclaimer: Im just learning compose recently and still digging deeper about the Snapshot
system, and it seemed like you're heading in the same direction as I do. I'd recommend to visit this link once in a while if your'e interested in the Snapshot
system. Apologies as well, I can't comment yet due to lack of reputation so I just posted my thought and current understanding of how State
and composition
work together.