@Arthur指出了一个很好的解决方案,使用verticalArrangement
.
这是一个更通用的解决方案:
同时,您可以获得LazyColumn
使用的大小onSizeChanged
,最后显示元素的底部位置layoutInfo
,并根据此信息添加到或Button
作为附近的子元素。item
LazyColumn
Column
@Composable
fun CustomLazyColumn(
modifier: Modifier,
items: List<String>,
button: @Composable () -> Unit
) {
val state = rememberLazyListState()
var listHeight by remember { mutableStateOf(0) }
val lastItemBottom by remember(items) {
derivedStateOf {
state.layoutInfo
.visibleItemsInfo
.lastOrNull()
?.let { it.offset + it.size }
?: 0
}
}
val shouldMoveButton = lastItemBottom < listHeight
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier.fillMaxHeight()
) {
LazyColumn(
state = state,
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.onSizeChanged { listHeight = it.height }
) {
items(items) { Text(it) }
if (!shouldMoveButton) {
item {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxWidth()
) {
button()
}
}
}
}
if (shouldMoveButton) {
button()
}
}
}
用法:
@Composable
fun TestView() {
val items = remember {
List(3) { it.toString() }.toMutableStateList()
}
Column {
Button(onClick = {
if (items.count() == 3) {
items.addAll(List(100) { it.toString() })
} else {
items.removeRange(3, items.indices.count())
}
}) {
Text("Add items")
}
CustomLazyColumn(
items = items,
button = {
Button(
onClick = {},
) {
Text("Button")
}
},
modifier = Modifier.fillMaxHeight(),
)
}
}
结果:
此方法的缺点是,当您删除许多项目时,例如将计数从 100 减少到 3,Button
将在单个帧的错误位置上可见,直到它可以向下移动。当然,这不是最常见的情况。
完美地应该使用 来完成SubcomposeLayout
,它位于 之下LazyColumn
,但是实施这个需要很多时间。