[英]Removing item from the list causes wrong display in LazyColumn
So here's an odd one, I think.所以我认为这是一个奇怪的问题。 I'm showing a list of
Textfields
in a LazyColoumn
.我在
Textfields
中显示文本LazyColoumn
列表。 The user can remove each of the textfields, but when doing so, it copies the value from REPLACE textfield.用户可以删除每个文本字段,但在这样做时,它会从 REPLACE 文本字段中复制值。
What's happening:发生了什么:
I have added 3 people: Person 1, Person 2, Person 3我添加了 3 个人:第 1 个人、第 2 个人、第 3 个人
I click remove Person 2.我单击删除人员 2。
Person 3 is now at Person 2's position (See the name), but copied Person 2' VALUE. Person 3 现在位于 Person 2 的 position(见名称),但复制了 Person 2 的 VALUE。
I manage the state like this:我这样管理 state:
private val peopleStateFlow = MutableStateFlow<List<Person>>()
I load the column like this:我像这样加载列:
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)
})
}
}
And I remove the person like this:我这样删除了这个人:
fun removePerson(person: Person) {
val indexOf = peopleState.value.indexOf(person)
val updateList = peopleState.value.toMutableList()
updateList.removeAt(indexOf)
peopleStateFlow.value = updateList
}
I even tried logging this list before and after the removal我什至尝试在删除前后记录此列表
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]
And it is seemingly being removed correctly, so the problem lies 100% with recompose, or how Compose manage a LazyColumn's or Textfield's state.它似乎被正确删除,所以问题 100% 在于重组,或者 Compose 如何管理 LazyColumn 或 Textfield 的 state。
I can't compile your code, though I suspect its similar to this , your LazyColumn
is only identifying the position of the items based on its index position and not something unique from its supplied data structure.我无法编译您的代码,但我怀疑它与此类似,您的
LazyColumn
仅根据其索引 position 识别项目的 position,而不是其提供的数据结构中的唯一内容。
And based on the official docs并基于官方 文档
By default, each item's state is keyed against the position of the item in the list or grid.
默认情况下,每个项目的 state 键控于列表或网格中项目的 position。 However, this can cause issues if the data set changes, since items which change position effectively lose any remembered state. If you imagine the scenario of LazyRow within a LazyColumn, if the row changes item position, the user would then lose their scroll position within the row.
但是,如果数据集发生变化,这可能会导致问题,因为更改 position 的项目实际上会丢失任何记住的 state。如果您想象 LazyColumn 中的 LazyRow 场景,如果行更改项目 position,则用户将在其中丢失滚动条 position该行。
So I'd assume you have something unique in your Person
properties that you can supply as a key
to your LazyColumn's
item
.所以我假设您的
Person
属性中有一些独特的东西,您可以将其作为key
提供给LazyColumn's
item
。
items(peopleStateSnap.size, key = { < something unique to person here > } ) { index ->
...
}
Update :更新:
There seems to be another way without using unique/stable keys
for a Lazy
item
when your data doesn't have one and if circumstances prevent you from modifying its structure.当您的数据没有唯一/稳定键并且情况阻止您修改其结构时,似乎还有另一种方法可以不对
Lazy
item
使用唯一/稳定keys
。
You can wrap your item's
composable inside a movableContentOf{...}
so their states are being tracked on Lazy
changes, something like this您可以将
item's
可组合项包装在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()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.