带有verticalScroll修饰符的Column内的LazyColumn会抛出异常

问题描述 投票:0回答:2

在我的一个可组合项中,

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")
  }
}
android android-jetpack-compose lazycolumn jetpack-compose-column
2个回答
4
投票

当您希望使用

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

获取它

0
投票

你应该使用嵌套滚动

这是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文档。

© www.soinside.com 2019 - 2024. All rights reserved.