简体   繁体   English

如何使用 Jetpack Compose AdapterList 保留滚动 position?

[英]How to retain scroll position with Jetpack Compose AdapterList?

I have an App with a List-Detail flow built with Jetpack Compose.我有一个使用 Jetpack Compose 构建的具有列表详细信息流的应用程序。 I would like to retain the scroll position when going back from the details view to the list view.从详细信息视图返回到列表视图时,我想保留滚动 position

Surfaces are exchanged based on the Model state:基于 Model state 交换表面:

@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 used to have a VerticalScroller and I was giving it a ScrollerPosition to retain the position after screen changes. ListScreen 曾经有一个 VerticalScroller,我给它一个 ScrollerPosition 以在屏幕更改后保留 position。 However, this solution does not work with AdapterList.但是,此解决方案不适用于 AdapterList。

This is how it used to be:以前是这样的:

@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()
            })
        }
    }
}

How can I make AdapterList retain the scroll position?如何使 AdapterList 保留滚动 position?

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

rememberScrollState() ? rememberScrollState()吗?

I think it can be extracted as a value or maybe the lerp() function can be used, by making it a custom Composable instead using Layout()我认为可以将其提取为一个值,或者可以使用 lerp() function,方法是使其成为自定义 Composable 而不是使用Layout()

Why not use lazycolumn instead?为什么不使用惰性列呢?

With Jetpack Compose 1.0 scroll position retention has became possible using rememberLazyListState() .随着 Jetpack Compose 1.0 滚动 position 使用rememberLazyListState()保留成为可能。

To retain the state, initialize the state variable somewhere high enough in the tree, for example, above the navigation.要保留 state,请在树中足够高的位置(例如导航上方)初始化 state 变量。 Then pass it to the LazyColumn .然后将其传递给LazyColumn

Here is an example with a Crossfade which retains the scroll position in the list when switching between list and details:这是一个Crossfade的例子,当在列表和细节之间切换时,它会在列表中保留滚动 position:

  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()
      }
    }
  }

The size of items must stay the same in order for this to work. items的大小必须保持不变才能使其正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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