Bites of Compose 1
Learn Jetpack Compose one bite at a time
I’m planning to write a series of short articles about Android’s Jetpack Compose UI framework. You can use it to test your understanding or maybe learn a few things along the way.
Situation 1
Take a look at the Composable below, what will happen if the button is clicked?
@Composable
fun Situation1() {
var name = "Guowei"
Column {
Text(name)
Button(onClick = { name = "Hello" }) {
Text("Change name!")
}
}
}
Answer
Nothing. The
name
is a plain Kotlin variable, changing it has no effect in Compose world.
Situation 2
A slight change of the previous case, what will happen if the button is clicked this time?
@Composable
fun Situation2() {
val name = mutableStateOf("Guowei")
Column {
Text(name.value)
Button(onClick = { name.value = "Hello" }) {
Text("Change name!")
}
}
}
Answer
Nothing! Let’s go through what happens when the button is clicked.
The State
name
’s value will be set to “hello”, and this will trigger a recompose of the view.So the
Situation2()
function will be executed again, andname
will be again assigned a new State with the inital value of “Guowei”.Hence, nothing changes.
Situation 3
What will happen if the button is clicked ?
@Composable
fun Situation3() {
val name = remember { mutableStateOf("Guowei") }
Column {
Text(name.value)
Button(onClick = { name.value = "Hello" }) {
Text("Change name!")
}
}
}
Answer
The text will be changed from “Guowei” to “Hello”.
Notice the State
name
is wrapped around aremember
function this time. So when the recomposition happens, thename
will not be initialized with a new object, but the previous object will be returned instead.So no matter how many times
Situation()
is executed, the name will always be the same object.
Situation 4
What will happen when the button is clicked?
@Composable
fun Situation4() {
var name by remember { mutableStateOf("Guowei") }
Column {
Text(name)
Button(onClick = { name = "Hello" }) {
Text("Change name!")
}
}
}
Answer
This is the same with Situation 3, but used the by
keyword to simplify things a bit.
Actually, the reason that we can use by
here, is because of these two ext functions from SnapshotState.kt
:
/**
* Permits property delegation of `val`s using `by` for [State].
*
* @sample androidx.compose.runtime.samples.DelegatedReadOnlyStateSample
*/
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T> State<T>.getValue(thisObj: Any?, property: KProperty<*>): T = value
/**
* Permits property delegation of `var`s using `by` for [MutableState].
*
* @sample androidx.compose.runtime.samples.DelegatedStateSample
*/
@Suppress("NOTHING_TO_INLINE")
inline operator fun <T> MutableState<T>.setValue(thisObj: Any?, property: KProperty<*>, value: T) {
this.value = value
}
Share this post
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Email