kotlin Compose LazyColumn键,排序项目时会弄乱卷动

a7qyws3x  于 2022-11-16  发布在  Kotlin
关注(0)|答案(2)|浏览(233)

我尝试对处于某个状态的项实现简单排序。
这将完美地工作,唯一的问题是,动画现在消失了,因为它没有一个关键点。

LazyColumn(
    state = listState,
) {
    items(items.size) { index ->
        val ticker = items[index]
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .animateItemPlacement(), // This won't work
        ) {
            Item(...)
        }
    }
}

但如果我尝试将其更改为:

items(items.size, key = { items[it].name }) { index ->

或者如果我用途:

items(items, key = { items[it].name }) { item ->

它将有动画,但它会移动项目以上和以下的当前滚动位置(即使你不移动)。想要的结果是,你留在顶部的项目,因为我们没有移动。
这是一个视图模型:
第一个

eqqqjvef

eqqqjvef1#

...唯一的问题是动画现在没有了,因为它没有关键点。
我创建了一个字母排序/过滤的示例,是的,没有item key动画停止工作。虽然我不知道为什么在你的情况下,你说有这个使动画工作,但它不工作在我的。

items(items) { item ->

但不管怎样,我会尽量做出假设,所以请和我一起坦白。
如果你想一想,如果没有animation,,对数据结构所做的任何更改都会立即呈现给UI,它只会简单地显示新的数据结构,但如果你对这些呈现更改添加一些延迟/持续时间animation),比如排序(例如,切换第一项和最后一项的位置):

  • 淡出最后定位的项目并淡入到第一个位置
  • 淡出第一个定位的项目并将其淡入到最后一个位置

该框架必须具有能够唯一*标识**这些位置(例如LazyColumn's item key)的东西,以便在进行动画渲染时不会出错,也可能避免仅为了跟踪更改而执行一些开销。
根据API文档,它需要一个键来激活

我们想要的结果是,您始终位于项目的顶部,因为我们没有移动。
不确定我是否理解正确,但是如果你想停留在第一个项目上,你可以利用LaunchedEffect,并使用列表的大小作为它的关键字,在每次过滤时对LazyColumn执行滚动操作。

LaunchedEffect(key1 = list.size) {
    lazyListState.animateScrollToItem(0) // scrolls to first item
}
s2j5cfk0

s2j5cfk02#

半修复问题:

LaunchedEffect(items.first()) {
    listState.animateScrollToItem(0)
}
LazyColumn{
        items(items, key = { it.id}) { item-> ...
}

有时动画会跳过,但90%的时间都能正常工作。如果我删除animateScrollToItem,动画看起来会更好,但之后会出现滚动位置问题。
编辑:因为我有搜索,我必须改进逻辑:

LaunchedEffect(items.firstOrNull()) {
    if (items.isNotEmpty() && searchQuery.isEmpty()) {
        listState.animateScrollToItem(0)
    }
}

现在,它的工作原理与开始时一样。

相关问题