[英]Jetpack Compose:LazyVerticalGrid within Column with verticalScroll modifier throws java.lang.IllegalStateException
I am trying to achieve this:我正在努力实现这一目标:
This section is inside my ProductDetailsScreen
composable.此部分在我的ProductDetailsScreen
creen 可组合内。 Here is the code:这是代码:
@Composable
fun ProductDetailsScreen(
modifier: Modifier = Modifier
) {
val scrollState = rememberScrollState()
Column(modifier = Modifier
.padding(horizontal = dimensionResource(id = R.dimen.dimen_24))
.verticalScroll(scrollState) // this makes the screen scrollable
) {
//images
ProductImages(
images = product?.productImage
)
//other stuff...
}
}
Here is also my ProductImages
composable:这也是我的ProductImages
可组合的:
@Composable
fun ProductImages(
modifier: Modifier = Modifier,
images: List<String>? = null,
) {
if (!images.isNullOrEmpty()) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.dimen_16))
) {
//title
ProductSectionTitle(
title = String.format(
stringResource(id = R.string.media_section_title),
images.size
)
)
//images
Row() {
ProductImage(modifier = Modifier.size(160.dp), image = images[0])
LazyVerticalGrid(
columns = GridCells.Fixed(2)
) {
items(images.subList(1, 5)) { image ->
ProductImage(modifier = Modifier.size(75.dp), image = image)
}
}
}
}
}
}
As you can see in the layout I have 5 images.正如您在布局中看到的,我有 5 张图片。 To achieve this layout I put the components within a Row
.为了实现这种布局,我将组件放在Row
中。 So The first image which is the biggest one is the first item of the Row
as you can see from this code:因此,最大的第一张图片是Row
的第一项,您可以从这段代码中看到:
//images
Row() {
ProductImage(modifier = Modifier.size(160.dp), image = images[0])
}
And I put the other images into the LazyVerticalGrid
cuz it divides images into the cells and I don't need to handle the calculation process by myself :我将其他图像放入LazyVerticalGrid
因为它将图像划分为单元格,我不需要自己处理计算过程:
LazyVerticalGrid(
columns = GridCells.Fixed(2)
) {
//since I already load the first image, I sublist the original one and take only 4 images
items(images.subList(1, 5)) { image ->
ProductImage(modifier = Modifier.size(75.dp), image = image)
}
}
But since it is in the Column
that has the .verticalScroll()
modifier it throws:但由于它位于具有.verticalScroll()
修饰符的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()). If you want to add a header before the list of items please add a header as a separate item() before the main items() inside the LazyColumn scope. There are could be other reasons for this to happen: your ComposeView was added into a LinearLayout with some weight, you applied Modifier.wrapContentSize(unbounded = true) or wrote a custom layout. Please try to remove the source of infinite constraints in the hierarchy above the scrolling container.
I don't want to give a fixed height to the LazyVerticalGrid
which fixes the issue.我不想给LazyVerticalGrid
一个固定的高度来解决这个问题。 I want to make it wrap its content.我想让它包装它的内容。 Is there any other way to achieve this layout or how can I prevent this error?有没有其他方法可以实现此布局或如何防止此错误?
What you can do is borrow and adapt the sample Grid.kt designed by the Jetpack Compose team.您可以做的是借用和改编 Jetpack Compose 团队设计的示例Grid.kt。 You can then use it everywhere in your project within LazyColumns.然后,您可以在 LazyColumns 的项目中的任何地方使用它。 You can use it like this:你可以像这样使用它:
VerticalGrid(
columns = 2
) {
(images.subList(1, 5)).forEach { image ->
ProductImage(modifier = Modifier.size(75.dp), image = image)
}
}
Setting a Modifier with fixed height for LazyVerticalGrid would solve it.为 LazyVerticalGrid 设置一个固定高度的修饰符可以解决这个问题。
I made this example with LazyColumn
but Column
with vertical scroll strong text also works when LazyVerticalGrid
has 160.dp height我用LazyColumn
做了这个例子,但是当LazyVerticalGrid
的高度为 160.dp 时,带有垂直滚动强文本的Column
也可以工作
@Composable
private fun CustomGrid() {
LazyColumn(
contentPadding = PaddingValues(8.dp),
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(10.dp)
) {
item {
Text("Title", fontSize = 20.sp)
}
item {
Row {
Image(
painter = painterResource(id = images.first()),
modifier = Modifier
.size(160.dp)
.clip(RoundedCornerShape(10.dp)),
contentScale = ContentScale.FillBounds,
contentDescription = null
)
Spacer(modifier = Modifier.width(10.dp))
LazyVerticalGrid(
verticalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp),
modifier = Modifier
.fillMaxWidth()
.height(160.dp),
columns = GridCells.Fixed(2)
) {
items(items = images.subList(1, 5)) { image ->
Image(
modifier = Modifier
.size(75.dp)
.clip(RoundedCornerShape(10.dp)),
painter = painterResource(id = image),
contentScale = ContentScale.FillBounds,
contentDescription = null
)
}
}
}
}
item {
Text("Another Title", fontSize = 20.sp)
}
}
}
This applies only to cases when nesting scrollable children without a predefined size inside another same direction scrollable parent.这仅适用于在另一个相同方向的可滚动父对象中嵌套没有预定义大小的可滚动子对象的情况。 For example, trying to nest a child LazyColumn without a fixed height inside a vertically scrollable Column parent:例如,尝试将没有固定高度的子 LazyColumn 嵌套在可垂直滚动的 Column 父级中:
// Throws IllegalStateException
Column(
modifier = Modifier.verticalScroll(state)
) {
LazyVerticalGrid {
// ...
}
}
Instead, the same result can be achieved by wrapping all of your composables inside one parent LazyColumn and using its DSL to pass in different types of content.相反,可以通过将所有可组合项包装在一个父 LazyColumn 中并使用其 DSL 传递不同类型的内容来实现相同的结果。 This enables emitting single items, as well as multiple list items, all in one place:这可以在一个地方发出单个项目以及多个列表项目:
LazyVerticalGrid {
item {
Header()
}
items(data) { item ->
Item(item)
}
item {
Footer()
}
}
reference: https://developer.android.com/jetpack/compose/lists#avoid-nesting-scrollable参考: https ://developer.android.com/jetpack/compose/lists#avoid-nesting-scrollable
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.