gpt4 book ai didi

android - Flow 不更新 Composable

转载 作者:行者123 更新时间:2023-12-05 00:18:01 28 4
gpt4 key购买 nike

我遇到了以下问题:

这是注册屏幕,上面有几个输入字段。当用户输入内容时,该值将传递给 ViewModel,设置为屏幕状态并通过 StateFlow 传回屏幕。从可组合项中,我正在观察此 StateFlow。问题在于 Composable 在向 Flow 发出新值后并未失效。

这是 ViewModel 代码:

class RegistrationViewModel : BaseViewModel() {

private val screenData = CreateAccountRegistrationScreenData.init()

private val _screenDataFlow = MutableStateFlow(screenData)
internal val screenDataFlow = _screenDataFlow.asStateFlow()

internal fun updateFirstName(name: String) {
screenData.firstName = name
updateScreenData()
}

private fun updateScreenData() {
viewModelScope.launch {
_screenDataFlow.emit(screenData.copy())
}
println()

}

}

这是可组合的代码:

@Composable
fun RegistrationScreen(navController: NavController, stepName: String) {
val focusManager = LocalFocusManager.current

val viewModel: RegistrationViewModel by rememberInstance()

val screenData by viewModel.screenDataFlow.collectAsState()

Scaffold {
ConstraintLayout(
modifier = Modifier
.fillMaxSize()
.pointerInput(Unit) {
detectTapGestures(onTap = {
focusManager.clearFocus()
})
},
) {
val (
textTopLabel,
textBottomLabel,
tfFirstName,
tfLastName,
tfEmail,
tfPassword,
btnNext
) = createRefs()

...
RegistrationOutlinedTextField(
value = screenData.firstName ?: "",
constraintAsModifier = {
constrainAs(tfFirstName) {
top.linkTo(textBottomLabel.bottom, margin = Padding30)
start.linkTo(parent.start)
end.linkTo(parent.end)
}
},
label = { Text("First Name", style = PoppinsNormalStyle14) },
leadingIcon = {
Image(
painter = painterResource(id = R.drawable.ic_user_login),
contentDescription = null
)
},
onValueChange = { viewModel.updateFirstName(it) }
)
}
}

在此先感谢您的帮助

最佳答案

在您的情况下,您的 MutableStateFlow 包含指向可变值的链接,这就是为什么当您传递 hashcode(根据所有字段值计算)的值时相同的原因,流程不会更新该值。

查看 Why is immutability important in functional programming?

data class 是一个很好用的工具,它将为您提供开箱即用的所有 copy,但您应该使用 var 并且只对您的字段使用 val 以避免错误。

此外,使用 MutableStateFlow,您始终可以访问 value,因此您无需将其存储在单独的变量中:

class RegistrationViewModel : BaseViewModel() {

private val _screenDataFlow = MutableStateFlow(CreateAccountRegistrationScreenData())
internal val screenDataFlow = _screenDataFlow.asStateFlow()

internal fun updateFirstName(name: String) {
_screenDataFlow.update { screenData ->
screenData.copy(firstName = name)
}
}
}

关于android - Flow 不更新 Composable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70146178/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com