[英]Fixed Grid inside LazyColumn in Jetpack Compose?
Currently in Jetpack Compose, this code throws an IllegalStateException
because you cannot nest two vertically scrolling Composables:目前在 Jetpack Compose 中,此代码会引发IllegalStateException
,因为您不能嵌套两个垂直滚动的 Composable:
@ExperimentalFoundationApi
@Composable
fun MyLazyColumn() {
LazyColumn {
item {
Text(text = "My LazyColumn Title")
}
item {
LazyVerticalGrid(cells = GridCells.Fixed(4)) {
items(10) {
Box(
modifier = Modifier
.size(50.dp)
.padding(5.dp)
.background(Color.Gray)
)
}
}
}
}
}
I do not want the grid itself to scroll, but simply display a fixed grid of the Composable that I pass into it.我不希望网格本身滚动,而只是显示我传递给它的 Composable 的固定网格。 Is there any workaround to displaying a non-scrolling grid inside a LazyColumn
?是否有任何解决方法可以在LazyColumn
内显示非滚动网格?
If you don't mind using an unstable API, you can use LazyVerticalGrid
and make item
take the full width with the span
parameter, as @Mustafa pointed out :如果您不介意使用不稳定的 API,您可以使用LazyVerticalGrid
并使用span
参数使item
采用全宽,正如@Mustafa指出的那样:
LazyVerticalGrid(
cells = GridCells.Fixed(spanCount),
) {
item(
span = { GridItemSpan(spanCount) }
) {
Text("Title")
}
items(10) {
Text(it.toString())
}
}
Until it's stable, it's recommended直到稳定为止, 推荐
using stable components like
LazyColumn
andRow
to achieve the same result.使用像LazyColumn
和Row
这样的稳定组件来达到相同的结果。
It can be done by implementing gridItems
to be used with LazyColumn
.可以通过实现与gridItems
一起使用的LazyColumn
来完成。
fun LazyListScope.gridItems(
count: Int,
nColumns: Int,
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
itemContent: @Composable BoxScope.(Int) -> Unit,
) {
gridItems(
data = List(count) { it },
nColumns = nColumns,
horizontalArrangement = horizontalArrangement,
itemContent = itemContent,
)
}
fun <T> LazyListScope.gridItems(
data: List<T>,
nColumns: Int,
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
key: ((item: T) -> Any)? = null,
itemContent: @Composable BoxScope.(T) -> Unit,
) {
val rows = if (data.isEmpty()) 0 else 1 + (data.count() - 1) / nColumns
items(rows) { rowIndex ->
Row(horizontalArrangement = horizontalArrangement) {
for (columnIndex in 0 until nColumns) {
val itemIndex = rowIndex * nColumns + columnIndex
if (itemIndex < data.count()) {
val item = data[itemIndex]
androidx.compose.runtime.key(key?.invoke(item)) {
Box(
modifier = Modifier.weight(1f, fill = true),
propagateMinConstraints = true
) {
itemContent.invoke(this, item)
}
}
} else {
Spacer(Modifier.weight(1f, fill = true))
}
}
}
}
}
Usage:用法:
LazyColumn {
item {
Text(text = "My LazyColumn Title")
}
// with count
gridItems(10, nColumns = 4) { index ->
Box(
modifier = Modifier
.size(50.dp)
.padding(5.dp)
.background(Color.Gray)
)
}
// or with list of items
gridItems(listOf(1,2,3), nColumns = 4) { item ->
Box(
modifier = Modifier
.size(50.dp)
.padding(5.dp)
.background(Color.Gray)
)
}
}
This accepted answer is great and works fine in case you have a small list of data and simple UI for grid items, but when your data is large and grid's items have a complex UI and state, it will become a laggy and heavy.如果您有少量数据列表和简单的网格项目 UI,这个公认的答案很好,并且工作正常,但是当您的数据很大并且网格的项目具有复杂的 UI 和状态时,它会变得迟钝和沉重。
In my case , I manage to solve this issue by making the LazyVerticalGrid as the container for grid's items and also the other content , now it looks like this :就我而言,我设法通过将 LazyVerticalGrid 作为网格项目和其他内容的容器来解决这个问题,现在它看起来像这样:
val spanCount = 2
LazyVerticalGrid(
modifier = modifier
.fillMaxWidth(),
cells = GridCells.Fixed(spanCount),
state = rememberLazyGridState(),
) {
item(
span = {
/** Take a full row */
GridItemSpan(currentLineSpan = spanCount)
}
) {
Column(
modifier = Modifier.fillMaxWidth()
) {
items.forEach {
/** Iterate over your items here */
}
}
}
items(
items = gridItems
){gridItem->
/** Grid items go here */
}
}
For me I have added height explicity and it worked fine with me for LazyverticalGrid inside lazy colum对我来说,我已经明确地添加了高度,它适用于我在惰性列中的 LazyverticalGrid
LazyVerticalGrid(
cells = GridCells.Fixed(3),
contentPadding = PaddingValues(5.dp),
modifier = Modifier
.layoutId("lazy_list")
.height(200.dp)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.