在我的一个可组合项中,
Lazycolumn
嵌套在 Column
可组合项内。我希望能够随 Column
一起滚动整个 Lazycolumn
。但是,在 verticalScroll
上指定 modifier
Column
属性会导致以下异常,导致应用程序崩溃。我该如何解决这个问题?
异常
java.lang.IllegalStateException: Vertically scrollable component was measured with an infinity maximum height constraints, which is disallowed. One of the common reasons is nesting layouts like LazyColumn and Column(Modifier.verticalScroll()).
可组合
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
.padding(bottom = 100.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
LazyColumn(
modifier = Modifier
.fillMaxWidth()
) {
items(
items = allItems!!,
key = { item ->
item.id
}
) { item ->
ShoppingListScreenItem(
navController = navController,
item = item,
sharedViewModel = sharedViewModel
) { isChecked ->
scope.launch {
shoppingListScreenViewModel.changeItemChecked(item!!, isChecked)
}
}
}
}
...
Button(
modifier = Modifier.padding(vertical = 24.dp),
onClick = {
navController.navigate(NavScreens.AddItemScreen.route) {
popUpTo(NavScreens.AddItemScreen.route) {
inclusive = true
}
}
}
) {
Text("Go to add item screen")
}
}
当您希望使用
LazyColumn
和 Constraints
来测量 Constraints.Infinity
的最大高度时,会发生这种情况,而这在错误日志中是不允许的。应该有一个固定的高度,否则你不应该有另一个具有相同方向的可滚动。
Column(
modifier = Modifier
// This is the cause
.verticalScroll(rememberScrollState())
) {
LazyColumn(
// and not having a Modifier that could return non-infinite max height contraint
modifier = Modifier
.fillMaxWidth()
) {
}
如果您不知道确切的高度,可以将
Modifier.weight(1f)
分配给 LazyColumn。
我所说的用 Constraints.Infinity 进行测量的意思是当您在使用的 Compose 中创建一个
Layout
时
Layout(modifier=modifier, content=content){
measurables: List<Measurable>, constraints: Constraints ->
}
您获得的子可组合项为
List<Measurable>
,您可以使用父级提供的 Constraints
进行测量,或者通过使用 Constraints.copy
更新现有可组合项来测量您认为合适的可组合项,或者在使用 Layout
构建自定义可组合项时修复一个可组合项。
val placeable = measurable.measure(constraints)
约束
min/max
width/height
根据大小修改器或滚动而变化。当有滚动且不使用任何大小修改器时,Constraints
返回
minHeight =0, maxHeight= Int.MAX_VALUE 为 Constraints.Infinity
Modifier.fillMaxWidth()
Modifier.fillMaxWidth().weight(1f)
使用不同的修饰符或滚动来检查
Constraints
的最简单方法是从 BoxWithConstraints
获取它
你应该使用嵌套滚动
这是google开发文档: https://developer.android.com/develop/ui/compose/touch-input/pointer-input/scroll
verticalScroll 仅适用于不同方向的嵌套滚动。就像:
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
) {
LazyRow(
modifier = Modifier
.fillMaxWidth()
) {
}
Row(
modifier = Modifier
.horizontalScroll(rememberScrollState())
) {
LazyColumn(
modifier = Modifier
.fillMaxHeight()
) {}
}
所以如果你想使用列嵌套的lazyColumn,你必须使用NestedScroll。
val nested = object : NestedScrollConnection {
override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
return super.onPostFling(consumed, available)
}
override fun onPostScroll(
consumed: Offset,
available: Offset,
source: NestedScrollSource
): Offset {
return super.onPostScroll(consumed, available, source)
}
override suspend fun onPreFling(available: Velocity): Velocity {
return super.onPreFling(available)
}
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
return super.onPreScroll(available, source)
}
}
Column(
modifier = Modifier.nestedScroll(nested)
) {
SideEffect {
Log.i("refresh", "Column")
}
LazyColumn {
}
LazyColumn(
modifier = Modifier
) {
}
}
这只是一个例子。具体要求请参考google dev文档。