【问题标题】:Jetpack Compose Paging 3 Auto scroll to the topJetpack Compose Paging 3 自动滚动到顶部
【发布时间】:2021-10-08 01:49:56
【问题描述】:

我用的是第3页,在显示数据的时候,发现如果页面切换回到最底部,数据会自动滚到最上面。

如果有两个项目会自动滚动到顶部,如果有一个项目就没有问题

val pagingItems = viewModel.windList.collectAsLazyPagingItems()

LazyColumn(Modifier.fillMaxSize()) {
    item {
        ...
    }
    items(pagingItems) { wind ->
        if (wind != null) {
            WindRow(navController, wind)
        }
    }
}

这样就可以了

LazyColumn(Modifier.fillMaxSize()) {
    items(pagingItems) { wind ->
        if (wind != null) {
            WindRow(navController, wind)
        }
    }
}

我不可避免地会使用多个项目。我该如何解决?

【问题讨论】:

  • 只是为了澄清 - 您是否要在分页项目列表中添加标题?
  • @dlam 没有,没有加header,跟加header有关系吗?
  • 请在您的问题中添加 [kotlin] 标签以添加代码高亮以更易于阅读
  • 我正在尝试理解您的问题 - 在您共享的第一个代码示例中,您似乎正在尝试在分页数据上方添加一些静态内容。以这种方式添加标题对您不起作用,还是您的意思是当您通过分页加载多个项目时?您能否准确说明它何时滚动到顶部或分享复制品?
  • @dlam 是的,通过 item 添加静态内容,但它不起作用。只要添加了静态内容,页面切换后页面就会滚动到顶部。

标签: kotlin android-jetpack-compose android-paging-3


【解决方案1】:

由于某种原因,您有可选的wind 元素,并且您当前的代码将创建一些零高度单元格,这可能会导致这种行为。如果可能,我建议您将其设为非可选。

同样,根据您的设计,您可能希望显示一个占位符,否则不要像这里这样添加空元素:

items(pagingItems.filterNotNull()) { wind ->
    WindRow(navController, wind)
}

或者,如果您的 null 对象可能变为非 null 并且您需要显示更新,您可以执行以下操作:

pagingItems.forEachIndexed { i, wind ->
    if (wind != null) {
        item(key = i) {
            WindRow(navController, wind)
        }
    }
}

如果这些都没有帮助,请将您的代码更新为minimal reproducible example

【讨论】:

  • 嗨菲利普!我试过你的答案,但无法解决。我想这不是 Compose 问题。这是一个分页 3 问题。根据官方文档,物品需要被包裹在状态中。 developer.android.google.cn/reference/kotlin/androidx/paging/…猜分页的个数和高度需要计算,多余的项不计算会滚到最上面。
  • @weifans 在文档示例中似乎不是可选的
  • 我目前的收尾方案是将多余的需要添加的item包裹在itemsIndexed(pagingItems) {index, wind -> }中,并根据索引添加需要添加的内容。此方法不会回滚到顶部
  • @dlam 或许你会有更好的解决方案,欢迎更新答案
  • @weifans 你可以在我的第一个示例中使用itemsIndexed,我的第二个示例已经包含供您使用的索引。如果这没有帮助,正如我所说,您需要提供minimal reproducible example
【解决方案2】:

如果我的理解正确,每次新页面加载都会导致您滚动到顶部,并在 LazyColumn 顶部使用静态项目。

如果没有在示例中实际尝试,我对这里发生的事情的最佳猜测是,在每次新页面加载时,paging-compose 会将列表重新提交给LazyColumn。由于始终存在一个静态项,因此 Compose 会将该项保持在视图中,并且由于该静态项位于顶部,因此具有滚动到顶部的效果。

对于解决方法,您可以使用 Paging 的 built-in support for headers

ViewModel.kt

val windList = Pager(..) { ..}
  .map { pagingData ->
    pagingData.insertHeaderItem(..)
  }
  .cachedIn(viewModelScope)
  .collectAsLazyPagingItems()

另外,我建议在项目中实现键映射,因为它将帮助您为 Compose 的LazyColumn 提供稳定的 id,使其了解如何在刷新或配置更改时恢复滚动位置。

【讨论】:

  • 我知道插入insertHeaderItem 是有效的,但是太不灵活了。静态内容无论在顶部还是底部,都会出现滚动到顶部的问题。在LazyColumn中,只要包含了多余的item就会出现问题,即使item为空也会出现问题。
  • 我猜你负责Paging3的工作。我认为上述解决方案是不可行的,也不是正确的解决方案。你需要重新考虑这个问题。
  • 明确地说,这是一种解决方法 - 分页撰写仍处于 alpha 阶段的一个重要原因是,这个问题就是其中之一。将增量更新发送到 UI 确实是“反组合”,但需要实现您想要的,因此有一个很大的开放式设计问题,即最好的方法是什么。
  • 您使用 itemsIndexed 的其他想法也是我们目前推荐的另一种方式 - 每个项目的映射是另一种工作方式(以及您将如何处理粘性标题),但不支持前置。
  • 明白,我们期待稳定版,也期待有更好的解决这个问题
猜你喜欢
  • 2021-12-31
  • 2022-01-05
  • 2021-05-26
  • 1970-01-01
  • 1970-01-01
  • 2023-01-31
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多