目前,Compose的LazyVerticalGrid DSL不支持设置spanSizeLookup。 但是,仍然可以通过编写自定义LazyItemScope并在其中使用LayoutInfo提供所需的功能。 下面是一个包含代码示例的解决方案:
@Composable
fun LazyVerticalGridWithDynamicSpan(
items: List,
spanCount: Int = 2,
itemContent: @Composable LazyItemScope.(T) -> Unit
) {
val lazyListState = rememberLazyListState()
val layoutInfo = remember {
GridLayoutInfo(
spanCount = spanCount,
)
}
LazyVerticalGrid(
cells = GridCells.Adaptive(minSize = 128.dp),
state = lazyListState,
layoutInfo = layoutInfo,
contentPadding = PaddingValues(8.dp)
) {
items(items = items) { item ->
DynamicSpanLazyItemScope(layoutInfo) {
itemContent(item)
}
}
}
}
// 自定义LazyItemScope,用于获取当前item所占的GridItemSpan
internal class DynamicSpanLazyItemScope(
private val layoutInfo: GridLayoutInfo,
content: @Composable LazyItemScope.() -> Unit
) : LazyItemScope {
private var span: Int? = null
init {
content()
span = span ?: layoutInfo.spanCount // 如果没有设置span,则一个item占一个GridItemSpan
}
override fun Modifier.requiredWidth(): IntPx {
return layoutInfo.cellSize * span!! + layoutInfo.horizontalGap * (span!! - 1)
}
override fun Modifier.requiredHeightForWidth(width: IntPx): IntPx {
return layoutInfo.getIntrinsicHeightForWidth(width) * span!!
}
override fun MeasureScope.measure(
measurable: Measurable,
constraints: Constraints,
layoutDirection: LayoutDirection
): MeasureResult {
val itemConstraints = Constraints(
minWidth = layoutInfo.cellSize * span!!,
maxWidth = layoutInfo.cellSize * span!!,
minHeight = layoutInfo.getIntrinsicHeightForWidth(constraints.maxWidth) * span!!,