gpt4 book ai didi

android-jetpack-compose - 如何在不自动滚动更改的情况下使用 LazyColumn animateItemPlacement()?

转载 作者:行者123 更新时间:2023-12-05 05:30:25 39 4
gpt4 key购买 nike

我在类似 list 的样式中使用 LazyColumn。该列表首先显示所有待完成的项目,最后显示所有已完成的项目。点击某个项目可切换是否完成。

这是我正在做的 MWE:

data class TodoItem(val id: Int, val label: String, var isDone: Boolean)

@Composable
fun TodoCard(item: TodoItem, modifier: Modifier, onClick: () -> Unit) {
val imagePainterDone = rememberVectorPainter(Icons.Outlined.Done)
val imagePainterNotDone = rememberVectorPainter(Icons.Outlined.Add)

Card(
modifier
.padding(8.dp)
.fillMaxWidth()
.clickable {
onClick()
}) {
Row {
Image(
if (item.isDone) imagePainterDone else imagePainterNotDone,
null,
modifier = Modifier.size(80.dp)
)
Text(text = item.label)
}
}
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun ExampleColumn() {
val todoItems = remember {
val list = mutableStateListOf<TodoItem>()
for (i in 0..20) {
list.add(TodoItem(i, "Todo $i", isDone = false))
}
list
}
val sortedTodoItems by remember {
derivedStateOf { todoItems.sortedWith(compareBy({ it.isDone }, { it.id })) }
}

LazyColumn {
items(sortedTodoItems, key = {it.label}) { item ->
TodoCard(item = item, modifier = Modifier.animateItemPlacement()) {
val index = todoItems.indexOfFirst { it.label == item.label }
if (index < 0) return@TodoCard
todoItems[index] = todoItems[index].copy(isDone = !todoItems[index].isDone)
}
}
}
}

Modifier.animateItemPlacement() 引入的一个副作用外,此方法效果很好:切换第一个当前可见的列表元素时,LazyListState 将滚动以跟随该元素.

这不是我想要的(我更希望它保持在相同的索引处)。

我找到了 this解决方法,建议在第一个元素发生变化时滚动回第一个元素,但这仅在列的第一项是当前显示的第一个元素时才解决问题。如果向下滚动使得第三个元素出现在最顶部可见并点击该元素,该列仍将滚动以跟随它。

有没有办法将自动滚动与项目放置动画分离?两者似乎都依赖于 LazyColumnkey 参数?

最佳答案

我没有尝试编译/运行你的代码,但看起来你有类似的问题 this , 它看起来像 LazyListState

中的这个
/**
* When the user provided custom keys for the items we can try to detect when there were
* items added or removed before our current first visible item and keep this item
* as the first visible one even given that its index has been changed.
*/
internal fun updateScrollPositionIfTheFirstItemWasMoved(itemsProvider: LazyListItemsProvider) {
scrollPosition.updateScrollPositionIfTheFirstItemWasMoved(itemsProvider)
}

我提出了一种可能的解决方法,即通过将其键设置为其索引而不是支持数据的唯一标识符来牺牲第一个项目的动画。

itemsIndexed(
items = checkItems.sortedBy { it.checked.value },
key = { index, item -> if (index == 0) index else item.id }
) { index, entry ->
...
}

虽然我还没有使用这种惰性 key 设置来回归任何用例,也无法解决您的问题,但您可以考虑尝试一下。

关于android-jetpack-compose - 如何在不自动滚动更改的情况下使用 LazyColumn animateItemPlacement()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74668917/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com