Mik*_*elT 5 android kotlin android-jetpack-compose lazycolumn compose-recomposition
我认为这是一个奇怪的情况。Textfields我正在显示a 中的列表LazyColoumn。用户可以删除每个文本字段,但这样做时,它会复制 REPLACE 文本字段中的值。
发生了什么:
我添加了 3 个人:第 1 人、第 2 人、第 3 人
我单击“删除人员 2”。
人员 3 现在位于人员 2 的位置(参见名称),但复制了人员 2 的 VALUE。
我这样管理状态:
private val peopleStateFlow = MutableStateFlow<List<Person>>()
Run Code Online (Sandbox Code Playgroud)
我像这样加载该列:
val peopleState = viewModel.peopleState.collectAsState()
LazyColumn {
val peopleStateSnap = peopleState.value
items(peopleStateSnap.size) { index ->
val person = peopleStateSnap[index]
ParticipantView(
person = person,
sharedOwed = sharedOwed.value,
onChangeListener = {
viewModel.updateOwed(person, it)
},
onRemoveClicked = {
viewModel.removePerson(person)
})
}
}
Run Code Online (Sandbox Code Playgroud)
我这样删除这个人:
fun removePerson(person: Person) {
val indexOf = peopleState.value.indexOf(person)
val updateList = peopleState.value.toMutableList()
updateList.removeAt(indexOf)
peopleStateFlow.value = updateList
}
Run Code Online (Sandbox Code Playgroud)
我什至尝试在删除之前和之后记录此列表
21:22:05.468 I qqq oldList=[1.0, 2.0, 0.0]
21:22:05.468 I qqq removed = 2.0
21:22:05.468 I qqq updateList=[1.0, 0.0]
Run Code Online (Sandbox Code Playgroud)
而且它似乎已被正确删除,因此问题 100% 在于重构,或者 Compose 如何管理 LazyColumn 或 Textfield 的状态。
我无法编译您的代码,尽管我怀疑它与此类似,您LazyColumn只是根据其索引位置来识别项目的位置,而不是其提供的数据结构中唯一的东西。
并根据官方文档
默认情况下,每个项目的状态都根据该项目在列表或网格中的位置进行设置。但是,如果数据集发生更改,这可能会导致问题,因为更改位置的项目实际上会丢失任何记住的状态。如果您想象一下 LazyColumn 中的 LazyRow 场景,如果该行更改了项目位置,则用户将丢失该行中的滚动位置。
因此,我假设您的Person属性中有一些独特的东西,您可以将其key作为LazyColumn's item.
items(peopleStateSnap.size, key = { < something unique to person here > } ) { index ->
...
}
Run Code Online (Sandbox Code Playgroud)
更新:
keys当Lazy item您的数据没有唯一/稳定并且情况阻止您修改其结构时,似乎还有另一种不使用唯一/稳定的方法。
您可以将item's可组合项包装在 a 中,movableContentOf{...}以便在更改时跟踪它们的状态Lazy,如下所示
LazyColumn {
items(peopleStateSnap.size) { index ->
val person = peopleStateSnap[index]
val movableContent = movableContentOf {
ParticipantView(
person = person,
sharedOwed = sharedOwed.value,
onChangeListener = {
viewModel.updateOwed(person, it)
},
onRemoveClicked = {
viewModel.removePerson(person)
})
}
movableContent()
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1041 次 |
| 最近记录: |