【问题标题】:How to retain scroll position with Jetpack Compose AdapterList?如何使用 Jetpack Compose AdapterList 保留滚动位置?
【发布时间】:2020-06-10 23:31:37
【问题描述】:

我有一个使用 Jetpack Compose 构建的带有 List-Detail 流程的应用程序。从详细信息视图返回到列表视图时,我想保留滚动位置

根据模型状态交换表面:

@Composable
private fun AppContent() {
    val scrollerPosition = ScrollerPosition()
    Crossfade(State.currentScreen) { screen ->
        Surface(color = MaterialTheme.colors.background) {
            when (screen) {
                is Screen.List -> ListScreen(scrollerPosition)
                is Screen.Details -> DetailsScreen(screen.transaction)
                is Screen.New -> NewScreen()
            }
        }
    }
}

ListScreen 曾经有一个 VerticalScroller,我给它一个 ScrollerPosition 以在屏幕更改后保留位置。但是,此解决方案不适用于 AdapterList。

以前是这样的:

@Composable
private fun TransactionsList(modifier: Modifier, scrollerPosition: ScrollerPosition) {
    Box(modifier = modifier.fillMaxSize().wrapContentSize(Alignment.Center)) {
        VerticalScroller(scrollerPosition = scrollerPosition) {
            AdapterList(State.transactions, itemCallback = { transaction ->
                TransactionListRow(transaction)
                ListDivider()
            })
        }
    }
}

如何让 AdapterList 保持滚动位置?

@Composable
private fun TransactionsList(modifier: Modifier, scrollerPosition: ScrollerPosition) {
    Box(modifier = modifier.fillMaxSize().wrapContentSize(Alignment.Center)) {
        AdapterList(State.transactions, itemCallback = { transaction ->
            TransactionListRow(transaction)
            ListDivider()
        })
    }
}

【问题讨论】:

  • 目前 (dev13) 这是不可能的,但是 compose 团队会在以后的版本中添加它。

标签: android kotlin android-jetpack-compose


【解决方案1】:

rememberScrollState()?

我认为可以将其提取为一个值,或者可以使用 lerp() 函数,方法是将其设为自定义 Composable,而不是使用 Layout()

为什么不改用lazycolumn?

【讨论】:

  • 我不明白这怎么不能回答问题?第一行包含有助于保持滚动位置的代码。第二行是一个替代方案,而第三行是一个很好的建议。
【解决方案2】:

在 Jetpack Compose 1.0 中,使用rememberLazyListState() 可以保留滚动位置。

要保留状态,请在树中足够高的位置初始化状态变量,例如导航上方。然后将其传递给LazyColumn

这是一个带有Crossfade 的示例,它在列表和详细信息之间切换时保留列表中的滚动位置:

  val listState = rememberLazyListState()

  Crossfade(screen) { scr ->
    Surface(color = colors.background) {
      when (scr) {
        is Screen.List -> LazyColumn(state = listState) {
              items(items) { item ->
                // here come the items
              }
            }
        is Screen.Details -> DetailsScreen()
      }
    }
  }

items 的大小必须保持不变才能正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多