LazyColum 嵌套 LazyRow
这种嵌套方式不会出现问题,上下滚动和水平滚动都没有问题
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(10) {
LazyRow(modifier = Modifier.padding(vertical = 10.dp)) {
items(20) {
Box(
modifier = Modifier
.padding(horizontal = 10.dp)
.size(100.dp)
.background(Color.LightGray, shape = RoundedCornerShape(10.dp))
) {
Text(text = it.toString(), modifier = Modifier.align(Alignment.Center))
}
}
}
}
}
LazyColum 嵌套 LazyColumn
这种嵌套方式会出现如下错误:
Process: com.qmai.mycomposeproject, PID: 10303
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.
/**
* lazyColum 嵌套 lazyColum
*/
@Composable
fun LazyColumAndLazyColum() {
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(10) {
Column(modifier = Modifier.fillMaxWidth()) {
//分隔开每个item
Spacer(modifier = Modifier.height(10.dp))
LazyColumn{
items(5) {
Box(
modifier = Modifier
.size(height = 50.dp, width = 200.dp)
.background(
Color.Green,
shape = RoundedCornerShape(10.dp)
)
) {
Text(text = it.toString())
}
}
}
}
}
}
}
出现错误的主要原因是 :LazyColum 在垂直方向的高度默认是无限大的,那么在LazyColum 中嵌套一个无限高度的 LazyColum,那么LazyColum就无法确定 item 的大小。
所以解决这个问题的方法有两种:
- 固定内部LazyColum 的高度大小。
- 通过循环添加 Compose 的方式,添加有大小的 item
1、固定内部LazyColum 的高度大小
/**
* lazyColum 嵌套 lazyColum
*/
@Composable
fun LazyColumAndLazyColum() {
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(10) {
Column(modifier = Modifier.fillMaxWidth()) {
//分隔开每个item
Spacer(modifier = Modifier.height(10.dp))
LazyColumn(modifier = Modifier.height( 100. dp) ) {
items(5) {
Box(
modifier = Modifier
.size(height = 50.dp, width = 200.dp)
.background(
Color.Green,
shape = RoundedCornerShape(10.dp)
)
) {
Text(text = it.toString())
}
}
}
}
}
}
}
如上代码块,红色标记部分,固定内部LazyColum的大小,实现LazyColum 嵌套 LazyColum
2、通过循环添加 Compose 的方式,添加有大小的 item
/**
* lazyColum 嵌套 lazyColum
*/
@Composable
fun LazyColumAndLazyColum() {
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(10) {
Column(modifier = Modifier.fillMaxWidth()) {
//分隔开每个item
Spacer(modifier = Modifier.height(10.dp))
repeat(5){
Box(
modifier = Modifier
.size(height = 50.dp, width = 200.dp)
.background(
Color.Green,
shape = RoundedCornerShape(10.dp)
)
) {
Text(text = it.toString())
}
}
}
}
}
}
LazyColum 嵌套 LazyVerticalGrid
这种嵌套方式也会出现如下错误,错误原因与 LazyColum 嵌套 LazyColum 原因一样,外层布局的内部嵌套了一个垂直方向无限大的布局
Process: com.qmai.mycomposeproject, PID: 11681
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.
解决方式也与 LazyColum 嵌套 LazyColum 一样,
- 固定内部布局的高度大小。
- 通过循环添加 Compose 的方式,添加有大小的 item
第一种方式我就不演示了,LazyColum 嵌套 LazyColum 有
通过循环的方式添加
/**
* 扩展 LazyColum 嵌套 LazyVerticalGrid
* @param data 数据
* @param columnCount 列
*/
fun <T> LazyListScope.gridItems(
data: List<T>,
key: ((index: Int) -> Any)? = null,
columnCount: Int,
modifier: Modifier = Modifier,
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
itemContent: @Composable BoxScope.(T) -> Unit,
) {
val size = data.count()
val rows = if (size == 0) 0 else 1 + (size - 1) / columnCount
items(rows, key = key) { rowIndex ->
Row(
horizontalArrangement = horizontalArrangement,
modifier = modifier
) {
for (columnIndex in 0 until columnCount) {
val itemIndex = rowIndex * columnCount + columnIndex
if (itemIndex < size) {
Box(
modifier = Modifier.weight(1F, fill = true),
propagateMinConstraints = true
) {
itemContent(data[itemIndex])
}
} else {
Spacer(Modifier.weight(1F, fill = true))
}
}
}
}
}
/**
* lazyColum 嵌套 LazyGrid 解决方案
*/
@Composable
fun LazyColumAndLazyGrid() {
LazyColumn(modifier = Modifier.fillMaxSize()) {
gridItems(listOf("我是第1","我是第2","我是第3","我是第4"), columnCount =4, modifier = Modifier.fillMaxWidth()) {
Box(
modifier = Modifier
.padding(start = 5.dp, end = 5.dp, bottom = 10.dp)
.border(
shape = RoundedCornerShape(4.dp),
width = 1.dp,
color = Color.Black.copy(alpha = 0.3f)
)
.fillMaxWidth()
.height(35.dp)
) {
Text(text = it, modifier = Modifier.align(Alignment.Center))
}
}
item {
Box(modifier = Modifier.fillMaxWidth().height(20.dp).background(Color.Green)) {
}
}
gridItems(listOf("我是第5","我是第6","我是第7","我是第8","我是第9","我是第10"), columnCount = 4, modifier = Modifier.fillMaxWidth()) {
Box(
modifier = Modifier
.padding(start = 5.dp, end = 5.dp, bottom = 10.dp)
.border(
shape = RoundedCornerShape(4.dp),
width = 1.dp,
color = Color.Black.copy(alpha = 0.3f)
)
.fillMaxWidth()
.height(35.dp)
) {
Text(text = it, modifier = Modifier.align(Alignment.Center))
}
}
}
}
LazyColum 嵌套 LazyHorizontalGrid
固定内部布局的高度大小,即可,这种嵌套方式比较少,也可以用其他方式代替。
这里就用第一种固定大小的方式。
@Composable
fun LazyColumAndLazyRowGrid() {
LazyColumn(modifier = Modifier.fillMaxSize()) {
item {
LazyHorizontalGrid(rows = GridCells.Fixed(4),Modifier.height(100.dp)) {
items(10) {
Box(
modifier = Modifier
.padding(start = 5.dp, end = 5.dp, bottom = 10.dp)
.border(
shape = RoundedCornerShape(4.dp),
width = 1.dp,
color = Color.Black.copy(alpha = 0.3f)
)
.fillMaxWidth()
.height(35.dp)
) {
Text(text = "我是第 $it", modifier = Modifier.align(Alignment.Center))
}
}
}
}
}
}