[英]Make last Item of the Compose LazyColumn fill rest of the screen
There is a regular list with some data and LazyColumn for showing it.有一个包含一些数据的常规列表和用于显示它的 LazyColumn。
LazyColumn {
items (list) { item ->
ListItem(item)
}
}
Simplified ListItem
looks like:简化的
ListItem
看起来像:
@Composable
fun ListItem(item: SomeItem) {
Row(
modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Min)
) {
//Some widgets
}
}
I need to set the footer's item (last in list) height to fill screen if there is not enough items for that.如果没有足够的项目,我需要设置页脚的项目(列表中的最后一个)高度以填充屏幕。 It's easy to find last item and provide some flag to
ListItem(item: SomeItem, isLast: Boolean)
, but I don't know how to set the item's height to achieve my goal.很容易找到最后一个项目并向
ListItem(item: SomeItem, isLast: Boolean)
提供一些标志,但我不知道如何设置项目的高度以实现我的目标。 Did anyone faced this problem?有人遇到过这个问题吗?
It's almost the same question as was asked here about RecyclerView .这与这里关于RecyclerView的问题几乎相同。 And the image from that question illustatrates it.
该问题的图像说明了这一点。
If your items are all same height and you have have info of how tall they are via static height or using Modifier.onSizeChanged{}
you can do this by getting height of the LazyColumn using BoxWithConstraints
maxHeight or rememberLazyListState().layoutInfo.viewportSize
如果您的项目都是相同的高度,并且您通过静态高度或使用
Modifier.onSizeChanged{}
了解它们的高度,您可以通过使用BoxWithConstraints
maxHeight 或rememberLazyListState().layoutInfo.viewportSize
获取 LazyColumn 的高度来做到这一点
@Composable
private fun ListComposable() {
val myItems = mutableListOf<String>()
repeat(4) {
myItems.add("Item $it")
}
BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.border(2.dp, Color.Cyan)
) {
itemsIndexed(myItems) { index: Int, item: String ->
if (index == myItems.size - 1) {
Text(
text = item,
modifier = Modifier
.fillMaxWidth()
.height((maxHeight - 50.dp * (myItems.size - 1)).coerceAtLeast(50.dp))
.background(Color.Green)
)
} else {
Text(
text = item,
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.background(Color.Red)
)
}
}
}
}
}
If you don't know total height until last item you will need to use SubcomposeLayout
with list that doesn't contain last item and pass LazyColumn height- (items.size-1) total height
as your last item's height.如果您直到最后一项才知道总高度,则需要将
SubcomposeLayout
与不包含最后一项的列表一起使用,并将LazyColumn height- (items.size-1) total height
作为最后一项的高度。
@Composable
fun DimensionMeasureSubcomposeLayout(
modifier: Modifier = Modifier,
mainContent: @Composable () -> Unit,
dependentContent: @Composable (IntSize, Constraints) -> Unit
) {
SubcomposeLayout(modifier = modifier) { constraints ->
// Subcompose(compose only a section) main content and get Placeable
val mainPlaceables: List<Placeable> = subcompose(SlotsEnum.Main, mainContent)
.map {
it.measure(constraints)
}
// Get max width and height of main component
var maxWidth = 0
var maxHeight = 0
mainPlaceables.forEach { placeable: Placeable ->
maxWidth += placeable.width
maxHeight = placeable.height
}
val maxSize = IntSize(maxWidth, maxHeight)
val dependentPlaceables = subcompose(SlotsEnum.Dependent) {
dependentContent(maxSize, constraints)
}.map {
it.measure(constraints)
}
layout(constraints.maxWidth, constraints.maxHeight) {
dependentPlaceables.forEach { placeable: Placeable ->
placeable.placeRelative(0, 0)
}
}
}
}
enum class SlotsEnum { Main, Dependent }
And use it as并将其用作
@Composable
private fun SubcomposeExample() {
val myItems = mutableListOf<String>()
repeat(15) {
myItems.add("Item $it")
}
val subList = myItems.subList(0, myItems.size - 1)
val lasItem = myItems.last()
val density = LocalDensity.current
DimensionMeasureSubcomposeLayout(
modifier = Modifier,
mainContent = {
LazyColumn(
modifier = Modifier.fillMaxWidth()
) {
items(subList) { item: String ->
Text(
text = item,
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.background(Color.Red)
)
}
}
},
dependentContent = { intSize, constraints ->
val lastItemHeight = with(density) {
(constraints.maxHeight - intSize.height).toDp().coerceAtLeast(50.dp)
}
LazyColumn(modifier = Modifier.fillMaxWidth()) {
if (myItems.size > 1) {
items(subList) { item: String ->
Text(
text = item,
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.background(Color.Red)
)
}
}
item {
Text(
text = lasItem,
modifier = Modifier
.fillMaxWidth()
.height(lastItemHeight)
.background(Color.Green)
)
}
}
}
)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.