因此,在我的数据集中,我存储了一个特殊的字符串.此字符串必须解析为树以供用户操作(查看、编辑、删除、合并、添加 node 等).对于 node 的添加和删除,我需要从活动文本字段中获取光标位置.在每个操作步骤中,我将树转换回其字符串表示形式,并将其存储到DataSet中,这将触发UI更新等.
然而,我现在有三个不同的真相来源:
-
ViewModel
,包含未分析字符串的数据库中的Stateflow
private val _uiState = MutableStateFlow(MyUnparsedStringFromDB())
val uiState: StateFlow<MyUnparsedStringFromDB> = _uiState.asStateFlow()
-
mutableStateOf
包含TreeComponent中的树对象
@Composable
fun TreeComponent(
modifier: Modifier = Modifier,
unparsedString: String,
onValueChange: (String) -> Unit,
) {
var root: MyTreeNode by remember { mutableStateOf(unparsedString.toTree()) }
val onNodeValueChange: (MyTreeNode, String) -> Unit = { node, newValue ->
node.text = newValue
onValueChange(root.toString())
}
...
// recursive logic to call NodeComponent on each node
NodeComponent(node, onNodeValueChange)
...
}
-
mutableStateOf
,包含NodeComponent中当前 node 的文本字段
@Composable
fun NodeComponent(
modifier: Modifier = Modifier,
node: MyTreeNode,
onNodeValueChange: (MyTreeNode, String) -> Unit,
) {
var textState by remember { mutableStateOf(TextFieldValue(node.text)) }
BasicTextField(
value = textState,
onValueChange = {
onNodeValueChange(node, it.text)
textState = it
}
// ...
)
}
最初,当我的目标是渲染这棵树或编辑node.text
字段时,这很有效.但是,当我try 执行更复杂的操作,如 node 拆分、添加、删除和合并时,它会变得非常令人头疼.
例如,现在,当我try 在当前光标位置将 node 一分为二时,树会按预期完全更新,并且正确的字符串表示形式会保存在数据集中.但textfield
状态更新不会被触发,除非我离开用户界面,然后返回它.我试图通过覆盖MyTreeNode.equals
函数以始终将FALSE输出为suggested by this answer来强制更新,但这并不起作用
那么,当所讨论的对象是复杂的时,我应该如何正确地进行状态提升?