Jetpack Compose的LazyColumn中的items在stickyHeader上滚动,但不会滚动到最后一个item。

15
我正在与Jetpack Compose的LazyColumn和stickyHeader功能挣扎。基本上,静态视图效果良好,但一旦开始滚动,项目将超过固定标题,滚动会出现奇怪的行为,并且最后一个项目永远不会可见,因为滚动总是反弹。

以下是它的外观:

enter image description here

这是可组合的代码:

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun CollectionsScreen(
    collectionsLive: LiveData<List<CollectionsView>>,
    onCollectionChanged: (ICalCollection) -> Unit
    /* some more hoisted functions left out for simplicity */
) {

    val list by collectionsLive.observeAsState(emptyList())
    val grouped = list.groupBy { it.accountName ?: it.accountType ?: "Account" }

    LazyColumn(
        modifier = Modifier.padding(8.dp)
    ) {

        item {
            Text(
                stringResource(id = R.string.collections_info),
                textAlign = TextAlign.Center,
                modifier = Modifier.padding(bottom = 16.dp)
            )
        }

        grouped.forEach { (account, collectionsInAccount) ->
            stickyHeader {
                Text(
                    account,
                    style = MaterialTheme.typography.titleLarge,
                    fontWeight = FontWeight.Bold,
                    modifier = Modifier.padding(
                        top = 16.dp,
                        start = 8.dp,
                        end = 16.dp,
                        bottom = 8.dp
                    )
                )
            }

            items(
                items = collectionsInAccount,
                key = { collection -> collection.collectionId }
            ) { collection ->

                CollectionCard(
                    collection = collection,
                    allCollections = list,
                    onCollectionChanged = onCollectionChanged,
                    /* some more hoisted functions left out for simplicity */
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(bottom = 8.dp)
                        .animateItemPlacement()
                        .combinedClickable(
                            //onClick = { onCollectionClicked(collection) }
                         )
                )
            }
        }
    }
}

我真的不确定是什么原因导致这个问题,因为代码本身从文档中提供的示例非常简单明了。只有CollectionCard本身是一个更复杂的结构。 我还尝试过删除标题文本(第一个项)并删除Card的Modifier.animateItemPlacement(),但没有任何差异,问题仍然存在... Composable本身在Fragment中的Compose View中使用,但没有嵌套滚动。 你有任何想法会导致这种奇怪的行为吗?或者在使用带有粘性标题的LazyColumn时可能会出现错误吗?
更新: 看起来问题与stickyHeader无关,而是与LazyColumn有关。如果我用“item”替换“stickyHeader”,问题仍然存在...只有当我用column替换lazyColumn时才能正常工作。但我相信一定有解决这个问题的方法...

我不确定,但可能是由于你的for循环导致了你的compose函数重新组合,这对性能非常不利。 - AgentP
1
循环在Compose中实际上不应该是一个问题... 代码遵循文档提供的示例:https://developer.android.com/jetpack/compose/lists#sticky-headers - Patrick Lang
我有完全相同的问题,你找到任何解决方案了吗? - Captain Allergy
1
为那个固定的页眉添加背景颜色。 - Tippu Fisal Sheriff
我建议您在决定使用任何方法之前,在问题跟踪器上创建一个问题。没有默认背景的stickyHeader似乎不太对。上次我检查时还没有相关问题。 - Uli
5个回答

10
一般来说,如果您正在使用 Material 或 Material3 主题,您可以将 stickyHeader 内容包装在一个 Surface 中,以自动使其不透明,并与您的主题标准(或定制)着色方案相匹配。 Surface 可让您将 stickyHeader 提升到表格的其他内容之上。
stickyHeader {
    Surface(Modifier.fillParentMaxWidth()) {
        Text("Header")
    }
}

您可以根据自己的喜好自定义 Surface。

我会为弹性问题创建另一个问题,因为它看起来是一个独立的问题。


这似乎解决了问题。 - Mike

2

设置stickyHeader的背景颜色将有所帮助。

stickyHeader {
                Text(
                    "text",
                    modifier = Modifier.padding(
                        top = 16.dp,
                        start = 8.dp,
                        end = 16.dp,
                        bottom = 8.dp
                    )
                   .background(colorResource(id = R.color.white))
                )
            }

3
无法解决项目超过粘性标题的问题。 - Android Dev
@AndroidDev 这个答案在 1.3.0-rc01 版本中对我有效。 - YaMiN

0

我不知道你是否已经解决了,但是尝试使用fillMaxWidth并设置背景。这段代码对我有效。

Text(
          account,
          style = MaterialTheme.typography.titleLarge,
          fontWeight = FontWeight.Bold,
          modifier = Modifier
              .padding(
                       top = 16.dp,
                       start = 8.dp,
                       end = 16.dp,
                       bottom = 8.dp
                      )
              .fillMaxWidth()
              .background(MaterialTheme.colors.background)
    )

0

为粘性标题提供一个背景。


不要直接提供答案,尝试编写详细的注释来解释解决方案,只要说明不太冗长即可。@Prashant Singh。 - DSDmark

-2

你只需要将stickyHeader{}替换为item{},就能得到预期的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接