admin管理员组

文章数量:1296866

How to wrap content height of a Column that has various Composables, one of them being another Column? I have a Card with a Column with 3 items, a title, a body (Column with n texts and scroll) and a bottom text. The idea is if the Card has more height than the screen, then, the user will have the possibility to scroll the body (body has a scroll).

The problem is that if the body has a lot of content (filling the entire screen height), the bottom text of the card is not displayed.

With the next sample you can click to enlarge or shorten the text to test the issue.

var long by remember{ mutableStateOf(true) }
Card(modifier = modifier.widthIn(max = 400.dp).fillMaxWidth().padding(16.dp),
    onClick = { long = !long }
) {
    Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
        Column(modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally) {
            Text(text = "1")
            Text(text = "2")

            val scrollState = rememberScrollState()
            Column(modifier = Modifier.verticalScroll(scrollState)) {
                if (long)
                    repeat(50) { Text(text = "body") }
                else
                    repeat(3) { Text(text = "body") }
            }

            Text(text = "3")
        }
    }
}

I tried using wrapContentHeight on the parent column (same result), also tried using weight(1f) in the child column (then the bottom text is visible always but the card is always stretched to full screen height), etc. I can't get the desired behaviour.

How to wrap content height of a Column that has various Composables, one of them being another Column? I have a Card with a Column with 3 items, a title, a body (Column with n texts and scroll) and a bottom text. The idea is if the Card has more height than the screen, then, the user will have the possibility to scroll the body (body has a scroll).

The problem is that if the body has a lot of content (filling the entire screen height), the bottom text of the card is not displayed.

With the next sample you can click to enlarge or shorten the text to test the issue.

var long by remember{ mutableStateOf(true) }
Card(modifier = modifier.widthIn(max = 400.dp).fillMaxWidth().padding(16.dp),
    onClick = { long = !long }
) {
    Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
        Column(modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally) {
            Text(text = "1")
            Text(text = "2")

            val scrollState = rememberScrollState()
            Column(modifier = Modifier.verticalScroll(scrollState)) {
                if (long)
                    repeat(50) { Text(text = "body") }
                else
                    repeat(3) { Text(text = "body") }
            }

            Text(text = "3")
        }
    }
}

I tried using wrapContentHeight on the parent column (same result), also tried using weight(1f) in the child column (then the bottom text is visible always but the card is always stretched to full screen height), etc. I can't get the desired behaviour.

Share Improve this question edited Mar 7 at 7:55 halfer 20.5k19 gold badges109 silver badges202 bronze badges asked Feb 11 at 17:45 NullPointerExceptionNullPointerException 37.7k80 gold badges230 silver badges403 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

Assign Modifier.weight(1f, fill = false) to scrollable Column.

Column(
    modifier = Modifier
        .weight(1f, fill = false)
        .verticalScroll(scrollState)
) {
    if (long)
        repeat(50) { Text(text = "body") }
    else
        repeat(3) { Text(text = "body") }
}

weight Modifier in Row or Column causes Composables with this Modifier to be measured after other Composables and set space is divided between the ones with weight Modifier based on their weight fractions.

If you set fill = false they are measured after other Composables still, but they occupy spaces as big as their content most, not available space all the time, after other other Composables are measured.

Size the element's height proportional to its weight relative to other weighted sibling elements in the Column. The parent will divide the vertical space remaining after measuring unweighted child elements and distribute it according to this weight. When fill is true, the element will be forced to occupy the whole height allocated to it. Otherwise, the element is allowed to be smaller - this will result in Column being smaller, as the unused allocated height will not be redistributed to other siblings.

本文标签: androidHow to wrap content height correctly in ComposeStack Overflow