I tried looking this up but could not find anything relevant.
I want to have a "full size" Column
inside a vertically scrollable Box
and this combination just doesn't seem to work. when I add the verticalScroll(rememberScrollState())
modifier to the Box
, it seems to "disable" the fillMaxSize()
modifier of the Column
The following code does not work as expected:
MyTheme {
Box(
modifier = Modifier
.fillMaxSize()
.border(2.dp, Color.Green) //for visual effect only
.verticalScroll(rememberScrollState())
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(2.dp)
.border(2.dp, Color.Red) //for visual effect only
) {
//some content
}
}
}
Expected result: Both Box
and Column
(green and red borders) fill the entire screen.
Actual result: Box
fills the screen, but Column
does not fill height
However if I remove the verticalScroll()
modifier from the Box
, I get the expected result:
MyTheme {
Box(
modifier = Modifier
.fillMaxSize()
.border(2.dp, Color.Green) //for visual effect only
//verticalScroll modifier removed
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(2.dp)
.border(2.dp, Color.Red) //for visual effect only
) {
//some content
}
}
}
As @AjayChandran noted, the simples solution is to add Modifier.height(IntrinsicSize.Max)
after verticalScroll
modifier.
This solution is simple, but may cause performance issues, since all the measurements inside the view are gonna be done twice. If you have performance problems in prod app version, consider using constant height - see detailed explanation below.
Modifier
.verticalScroll(scrollState)
.height(IntrinsicSize.Max)
verticalScroll
wraps the height of the content, and can be stretched to very long, so the scope has Constraints.Infinity
for maxHeight
constraint.
From fillMaxHeight
documentation
If the incoming maximum height is Constraints.Infinity this modifier will have no effect.
That's why you need to set height
explicitly.
Consider switching to LazyColumn
(which has fillParentMaxHeight()
for this exact purpose) or to Pager
(which is made explicitly for such cases).
Also, as @AdrianK pointer out, with regular scrollable
you can wrap your view with BoxWithConstraints
, and use maxHeight
to set height
of your view.
BoxWithConstraints {
Box(
modifier = Modifier
.fillMaxSize()
.border(2.dp, Color.Green)
.verticalScroll(rememberScrollState())
) {
Column {
repeat(2) {
Column(
modifier = Modifier
// fillMaxWidth instead of fillMaxSize
.fillMaxWidth()
// explicit height modifier
.height(this@BoxWithConstraints.maxHeight)
.padding(2.dp)
.border(2.dp, Color.Red)
) {
//some content
}
}
}
}
}
Result: