如何在Jetpack Compose中使LazyColumn的子项占据剩余的高度

5

我能否使LazyColumn中的一个项目仅占据可用的剩余高度?我试过使用fillParentMaxSize,但它会使该项与LazyColumn大小相同,因此我无法将另一个项目放在列表顶部,例如我想要随内容一起滚动的标题。

示例代码:

@Composable
fun LazyColumnTest() {
    LazyColumn(
        modifier = Modifier.fillMaxSize()
    ) {
        item {
            Column {
                Text(text = "This is a title", style = MaterialTheme.typography.h4)
                Text(text = "With a subtitle", style = MaterialTheme.typography.subtitle1)

            }
        }
        item {
            OtherLayout(modifier = Modifier.fillParentMaxHeight())
        }
    }
}

@Composable
fun OtherLayout(modifier: Modifier = Modifier) {
    Box(modifier = modifier.fillMaxSize()) {
        Icon(
            Icons.Default.Close,
            contentDescription = null,
            modifier = Modifier
                .size(150.dp)
                .align(Alignment.TopCenter)
        )
        Button(
            onClick = { /*TODO*/ },
            modifier = Modifier
                .padding(bottom = 16.dp)
                .align(Alignment.BottomCenter)
        ) {
            Text(text = "Button at bottom")
        }
    }
}

这是当前的结果。按钮在屏幕外,所以我需要滚动才能看到它。 样例

更新

在上面的示例中,想法是使用OtherLayout作为状态。我可以显示items或者这个带有底部按钮(例如重试按钮)的OtherLayout。 如果我在ScrollView上添加fillViewport="true",那么我可以在视图系统上做大致相同的布局。可以在另一个视图上添加gravity="bottom",它将保持在屏幕底部。

我会在这里添加一个新的示例,以查看是否能更好地解释。

@Composable
fun LazyColumnTest() {
    LazyColumn(
        modifier = Modifier.fillMaxSize()
    ) {
        item {
            // need to scroll with the content
            Header()
        }
        items(2) { position ->
            Text(text = "Item $position")
        }
        item {
            // need to stay at bottom if the items not fill the screen
            // and scroll with the content if has a lot of items
            Footer(modifier = Modifier)
        }
    }
}

@Composable
private fun Header() {
    Column {
        Text(text = "This is a title", style = MaterialTheme.typography.h4)
        Text(text = "With a subtitle", style = MaterialTheme.typography.subtitle1)
    }
}

@Composable
fun Footer(modifier: Modifier = Modifier) {
    Column(modifier = modifier.fillMaxWidth()) {
        Text(text = "This is a default footer that cannot be changed")
        Button(
            onClick = { /*TODO*/ },
            modifier = Modifier
                .padding(bottom = 16.dp)
        ) {
            Text(text = "With a button")
        }
    }
}


在这个例子中,我需要页眉和页脚随内容滚动,但如果项目没有填满整个屏幕,页脚会保持在屏幕底部。

sample2


您可以将按钮移动到LazyColumn之外。类似于:https://dev59.com/VXkPtIcB2Jgan1znoq01#73636819 - Gabriele Mariotti
我更新了示例代码,试图使其更加清晰明了。 - Fillipe Duoli
1个回答

1

使用item函数,您可以将另一个项目添加到LazyColumn的可滚动内容中。

如果您希望LazyColumn仅占用剩余的可用高度,并且页脚不随列表滚动,则可以将页脚移出LazyColumn并将weight修饰符应用于LazyColumn

类似于:

Column(){
    Header()

    LazyColumn(Modifier.weight(1f)) {
        //....
    }

    Footer() //your Box
}

针对你的情况:

Column {

    //Header
    Box(Modifier.fillMaxWidth().height(30.dp).background(Red))

    LazyColumn(Modifier.weight(1f)) {
        items(itemsList){
            Text("Item $it")
        }
    }

    //Footer
    OtherLayout()
}

使用:

@Composable
fun OtherLayout(modifier: Modifier = Modifier) {
    Box(modifier = modifier.fillMaxWidth()) {
        //..
    }
}

enter image description here


在我的情况下,项目内容是一个默认布局,在底部已经有一个按钮,所以我试图使用这个相同的布局而不将其分成更多部分。 =/ - Fillipe Duoli
@FillipeDuoli,您的评论不够清晰。在我的示例中,您有一个标题和一个LazyColumn,它仅占用剩余可用高度,将OtherLayout放置在屏幕底部。 - Gabriele Mariotti
1
@FillipeDuoli,我认为你应该重新考虑你的设计或者问题,因为在无限高度可滚动的情况下,你不可能将按钮显示在底部,除非采用Gabriele的建议,使你的LazyColumn占据屏幕适当的空间,但这会“破坏你的代码”,或者你可以强制你的LazyColumn滚动到底部。 - z.g.y
@z.y 这就是重点,“如果”可以这样做的话。我知道如何通过更改可组合部件的结构来实现所需的布局。在视图系统中,如果我在ScrollView上添加 android:fillViewport="true",我可以做到大致同样的事情。@GabrieleMariotti 在我做的这个例子中,OtherLayout 不是页脚。我的想法更像是一个状态。我可以显示 items 或者这个布局,像一个底部有重试的错误消息。我将添加一个新的例子,但带有页脚,看看是否有其他方法来尝试使我的问题更清晰。 - Fillipe Duoli
@FillipeDuoli “像是一个底部有重试按钮的错误消息” - 这听起来像是 SnackbarToast 或者 BottomSheetDialog - z.g.y

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