Bie*_*Dav 11 kotlin android-jetpack-compose mutablestateof
我一直在使用 Jetpack Compose Desktop。我注意到一些我真的不明白的事情:
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
@Composable
@Preview
fun App() {
var text by mutableStateOf("Hello, World!")
MaterialTheme {
TextField(text, onValueChange = { text = it })
Button(onClick = {
text = "Hello, Desktop!"
}) {
Text(text)
}
}
}
fun main() = application {
Window(onCloseRequest = ::exitApplication) {
App()
}
}
Run Code Online (Sandbox Code Playgroud)
为什么我可以更改 中的文本TextField?我认为在每次重组时,可变状态都会使用初始值重新实例化:所以Text应该无法更改
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
@Composable
@Preview
fun App() {
var text by mutableStateOf("Hello, World!")
Column {
TextField(text, onValueChange = { text = it })
Button(onClick = {
text = "Hello, Desktop!"
}) {
Text(text)
}
}
}
fun main() = application {
Window(onCloseRequest = ::exitApplication) {
App()
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您将 替换MaterialTheme为 a,Column它会突然按预期工作,并且您无法更改 中的文本TextField。
这是为什么?这是一个错误还是一个功能?
Thr*_*ian 15
这是 Compose 的一个关于范围界定和智能重组的功能。你可以在这里查看我的详细回答。
真正让你的整个Composable重构是Column使用inline关键字定义的。
@Composable
inline fun Column(
modifier: Modifier = Modifier,
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
content: @Composable ColumnScope.() -> Unit
) {
val measurePolicy = columnMeasurePolicy(verticalArrangement, horizontalAlignment)
Layout(
content = { ColumnScopeInstance.content() },
measurePolicy = measurePolicy,
modifier = modifier
)
}
Run Code Online (Sandbox Code Playgroud)
假设您有一个Composable在合成时最初设置背景颜色,并在每次重新合成时更改它,从而创建自己的范围。没有的 lambdainline被视为范围。
@Composable
fun RandomColorColumn(content: @Composable () -> Unit) {
Column(
modifier = Modifier
.padding(4.dp)
.shadow(1.dp, shape = CutCornerShape(topEnd = 8.dp))
.background(getRandomColor())
.padding(4.dp)
) {
content()
}
}
Run Code Online (Sandbox Code Playgroud)
和
@Composable
fun App2() {
var text by mutableStateOf("Hello, World!")
RandomColorColumn {
TextField(text, onValueChange = { text = it })
Button(onClick = {
text = "Hello, Desktop!"
}) {
Text(text)
}
}
}
Run Code Online (Sandbox Code Playgroud)
还有一个与Column
@Composable
fun App() {
var text by mutableStateOf("Hello, World!")
Column(modifier = Modifier.background(getRandomColor())) {
TextField(text, onValueChange = { text = it })
Button(onClick = {
text = "Hello, Desktop!"
}) {
Text(text)
}
}
}
Run Code Online (Sandbox Code Playgroud)
随机颜色功能
fun getRandomColor() = Color(
red = Random.nextInt(256),
green = Random.nextInt(256),
blue = Random.nextInt(256),
alpha = 255
)
Run Code Online (Sandbox Code Playgroud)
您将看到每次更改文本时列背景颜色都会更改,但不会更改App2()