【问题标题】:Jetpack Compose: Not able to show text in TextFieldJetpack Compose:无法在 TextField 中显示文本
【发布时间】:2021-07-16 14:40:22
【问题描述】:

最近我在玩 Jetpack Compose,发现文本可能不会显示在 TextField 中。

所以我有一个ViewModelFlowViewState

在我的Compose 文件中,我有类似这样的内容:

@Composable
internal fun TestScreen() {
    val state by viewModel.state.collectAsState()
    TestScreen {
        viewState = state,
        actioner = { ... }
    }
}

@Composable
private fun TestScreen(viewState: ViewState, actioner: () -> Unit) {
    var name by remember {
        mutableStateOf(
            TextFieldValue(viewState.name)
        )
    }
    Surface {
        ....
        Column {
            ....

            OutlinedTextField(
                ...
                value = name,
                onValueChange = { textFieldValue -> 
                    name = textFieldValue
                    actioner(...)
                }
            )
        }
    }
}

OutlineTextField 永远不会显示 viewState.name 内部已有的内容

但是,如果我改变这个:

    var name by remember {
        mutableStateOf(
            TextFieldValue(viewState.name)
        )
    }

到这里:

    var name = TextFieldValue(viewState.name)

显然它可以显示viewState.name中的值。

根据文档 (https://developer.android.com/jetpack/compose/state#state-in-composables),它建议使用 remembermutableStateOf 来处理更改。

如果有人可以帮助我解释为什么带有remember 的代码不起作用但直接分配的值起作用,我将不胜感激?

编辑

viewState.nameString

我通过执行以下操作“部分解决”了这个问题:

    var name by remember {
        mutableStateOf(
            TextFieldValue("")
        )
    }
    
    name = TextFieldValue(viewState.name)

然后可以显示名称。但是看起来不太对劲?

【问题讨论】:

    标签: android android-jetpack-compose


    【解决方案1】:

    remember 仅用于确保在重组时,mutableStateOf 对象的值不会重新初始化为初始值。

    例如,

    @Composable
    fun Test1(){
     var text by mutableStateOf ("Prev Text")
     Text(text)
      Button(onClick = { text = "Updated Text" }){
          Text("Update The Text")
      }
    }
    

    不会更新按钮单击时的文本。这是因为按钮单击将更改 mutableStateOf text,这将触发重组。但是,当控件到达 Composable 的第一行时,它会将变量 text 重新初始化为“Prev Text”。

    这就是remember 的用武之地。

    如果将上面的初始化更改为

    var text by remember { mutableStateOf ("Prev Text") },

    它将告诉 compose 跟踪这个变量,并“记住”它的值,并在重新组合时再次使用它,当控件再次到达初始化逻辑时。因此,那里的记忆充当“守卫”,它不会让控件进入初始化逻辑,并返回它当前存储的变量的最新记忆值。

    【讨论】:

    • 感谢您的解释!
    • 您还有什么要问的吗?
    • 是的。所以remember真的是要记住状态,即使在其他地方发生变化也会保持初始值,对吧?
    • 嘿,mutableStateOf 不能与任何值一起使用。仅支持某些类型。 TextFieldValue 不是其中之一。
    • 恐怕不行。我知道所有原始类型都受支持,我认为仅此而已。另外,支持listOf(...),不可变列表
    猜你喜欢
    • 2020-03-11
    • 1970-01-01
    • 2021-10-01
    • 2021-11-07
    • 2021-09-20
    • 1970-01-01
    • 2022-08-18
    • 2021-11-14
    • 1970-01-01
    相关资源
    最近更新 更多