我如何从jetpack compose中的viewModel更改TextField值中的值

Yun*_*ang 11 android textfield viewmodel kotlin android-jetpack-compose

我在我的项目中使用,并且不知道如何更改TextFieldViewModel 中的 a 值。

在我的活动中:

...
@Composable
fun myView() {
    var dName = remember {
        mutableStateOf(TextFieldValue(""))
    }
    TextField(
        value = dName.value, 
        onValueChange = { dName.value = it }, 
        modifier = Modifier.fillMaxWidth()
    )
}
...
Run Code Online (Sandbox Code Playgroud)

在我的视图模型中:

...
var dName = MutableStateFlow("")
...
Run Code Online (Sandbox Code Playgroud)

我想调用dName.value = "test" 我的 ViewModel 并更改TextField. 我怎样才能做到这一点?

Pha*_*inh 11

您也可以使用mutableStateOf代替MutableStateFlow. 我认为这很简单。

视图模型

var dname by mutableStateOf("init value")
Run Code Online (Sandbox Code Playgroud)

可组合的

TextField(
    value = viewModel.dname,
    onValueChange = { viewModel.dname = it }
)
Run Code Online (Sandbox Code Playgroud)

在 中ViewModel,当你想改变这个值时,你可以调用dname = "test"


Noa*_*oah 6

假设您有一个对名为 的 viewModel 的引用viewModel,您只需调用viewModel.name.collectAsState(). 但除此之外,我建议通过将 MutableStateFlow 设为私有并向可组合项公开不可变的 StateFlow 和 setter 方法,将数据逻辑保留在 ViewModel 中。

// ViewModel
private val _name = MutableStateFlow("")
val name = _name.asStateFlow()

fun setName(name: String) {
  _name.value = name
}
Run Code Online (Sandbox Code Playgroud)
// Composable
val name = viewModel.name.collectAsState()
TextField(
  value = name,
  onValueChange = viewModel::setName
)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我没有remember { mutableStateOf(...) }在这里使用,因为 ViewModel 中的 StateFlow 是唯一的事实来源。

您强制设置可组合项值的方法在 Jetpack Compose 提供的声明式 API 中没有意义。

尝试阅读 Jetpack compose 中的声明式/命令式 UI 和状态以及 kotlin flow 以了解更多信息。

  • 来自官方文档:https://developer.android.com/jetpack/compose/text#state-mgmt *避免使用 StateFlow 等反应式流来表示 TextField 状态,因为这些结构会引入异步延迟。相反,使用 MutableState* (6认同)