简体   繁体   English

从列表中删除项目会导致 LazyColumn 中显示错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM