Dec*_*ine 2 android android-jetpack-compose
我有 2 个可变状态ViewModel
,希望它们观察我的可组合项中的文本字段。
ViewModel
:
@HiltViewModel
class AddEditTransactionViewModel @Inject constructor(
private val moneyManagerUseCases: MoneyManagerUseCases
) : ViewModel() {
private val _transactionDescription = mutableStateOf("")
val transactionDescription: State<String> = _transactionDescription
private val _transactionAmount = mutableStateOf("")
val transactionAmount: State<String> = _transactionAmount
Run Code Online (Sandbox Code Playgroud)
Composable
:
@Composable
fun AddEditTransactionScreen(
navController: NavController,
viewModel: AddEditTransactionViewModel = hiltViewModel(),
) {
// This works
var descriptionState by remember { mutableStateOf("") }
var amountState by remember { mutableStateOf("") }
// This doesn't work
var viewModelDescriptionState = viewModel.transactionDescription.value
var viewModelAmountState = viewModel.transactionAmount.value
Column(
modifier = Modifier
.fillMaxSize()
.padding(8.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
TextField(
value = viewModelDescriptionState,
onValueChange = { viewModelDescriptionState = it },
label = { Text(text = "Description") })
Spacer(modifier = Modifier.padding(20.dp))
TextField(
value = viewModelAmountState,
onValueChange = { viewModelAmountState = it },
label = { Text(text = "Amount") },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
)
Run Code Online (Sandbox Code Playgroud)
如果我使用可组合项中的状态,它会起作用,但这违背了 ViewModel 的目的。
第一行:
var descriptionState by remember { mutableStateOf(") }
Run Code Online (Sandbox Code Playgroud)
它之所以有效,是因为您正在更新通过委托的值mutableState
。如果你看看在没有委托的情况下如何做同样的事情,那就更容易理解了:
val descriptionState = remember { mutableStateOf("") }
//...
descriptionState.value = "new value"
Run Code Online (Sandbox Code Playgroud)
remember
将在重组之间保存相同的对象,但该对象具有value
正在更改的字段。
另一方面,这里:
var viewModelDescriptionState = viewModel.transactionDescription.value
Run Code Online (Sandbox Code Playgroud)
您创建了一个局部变量,并且在重组之间不会保存任何更改。
这通常可以通过在视图模型中创建 setter 函数来解决。您还可以在视图模型中使用委托,如果您想限制它在没有setter的情况下进行更新,您可以添加private set
, 而不是使用private _variable
和public variable
:
var transactionDescription by mutableStateOf("")
private set
fun updateTransactionDescription(newValue: String) {
transactionDescription = newValue
}
Run Code Online (Sandbox Code Playgroud)
这被认为是最佳实践,因为 setter 可以包含比简单更新值更多的逻辑。在只需要存储的情况下,可以去掉该private
部分直接更新,不需要setter函数。
您可以在 Compose文档中找到有关状态的更多信息,包括解释基本原理的YouTube 视频。
归档时间: |
|
查看次数: |
5453 次 |
最近记录: |