[英]LazyHorizontalGrid inside LazyColumn
我有一個 LazyColumn 並且在它里面我想顯示一個有兩列的水平行,所以我正在嘗試 LazyHorizontalGrid 來實現它。 但是我的應用程序崩潰並出現異常 - IllegalArgumentException: LazyHorizontalGrid's height should be bound by parent
。 下面是我正在使用的代碼,任何人都可以幫助修復它或任何其他方式,通過它我可以使一行有兩列。
@Composable
fun HomeItem1() {
Surface(modifier = Modifier.nestedScroll(rememberViewInteropNestedScrollConnection())) {
LazyColumn {
//other contents
item {
LazyHorizontalGrid(
rows = GridCells.Fixed(3),
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
items(arrayList.size) {
Text(arrayList[it])
}
}
}
}
}
}
所有你需要事先計算網格的高度。
@Composable
fun HomeItem1() {
Surface(modifier = Modifier.nestedScroll(rememberViewInteropNestedScrollConnection())) {
LazyColumn {
//other contents
item {
LazyHorizontalGrid(
modifier = Modifier.height(176.dp), // itemHeight * rowCount + verticalSpacing * (rowCount - 1)
rows = GridCells.Fixed(3),
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
items(arrayList.size) {
Text(arrayList[it], modifier = Modifier.height(48.dp))
}
}
}
}
}
}
當您嘗試使用Constraints.Infinity
測量相應維度時,會出現帶有維度的LazyList
異常。 我在這個答案中解釋了如何基於修飾符Modifier.scroll()
應用約束。 此外,使用像LazyColumn
這樣的可滾動父 Composable 創建具有無限高度的 Constraints, LazyRow
創建具有無限寬度的 Constraints。
您可以將 Modifier.height(maxHeight) 與 maxHeight 從
您可以使用Modifier.height(maxHeight)
或Modifier.layout{}
並將最大高度限制為屏幕高度或以像素為單位的選定高度。 約束返回將與布局 function 一起使用的以 px 為單位的尺寸。通過用 BoxWithConstraints 包裝它從父級獲取約束高度返回非無限高度
@Composable
private fun Sample() {
val arrayList = remember {
mutableStateListOf<String>().apply {
repeat(40) {
add("Item $it")
}
}
}
Column(
modifier = Modifier
.border(4.dp, Color.Green)
.fillMaxSize()
) {
BoxWithConstraints {
val parentConstraints = this.constraints
val maxHeight = this.maxHeight
LazyColumn {
//other contents
item {
Image(
modifier = Modifier
.height(200.dp)
.fillMaxWidth(),
painter = painterResource(id = R.drawable.landscape2),
contentDescription = null,
contentScale = ContentScale.FillBounds
)
}
item {
LazyHorizontalGrid(
modifier = Modifier
.border(2.dp, Color.Red)
// Alternative 1
// .height(maxHeight)
// Alternative 2
.layout { measurable, constraints ->
val placeable = measurable.measure(
constraints.copy(maxHeight = parentConstraints.maxHeight)
)
layout(placeable.width, placeable.height) {
placeable.placeRelative(0, 0)
}
},
rows = GridCells.Fixed(3),
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
items(arrayList.size) {
Box(
modifier = Modifier
.shadow(2.dp, RoundedCornerShape(8.dp))
.background(Color.White)
.aspectRatio(1f)
.padding(2.dp)
) {
Text(arrayList[it])
}
}
}
}
}
}
}
}
上面的示例創建了一個具有全屏高度的 LazyHorizontalGrid,我添加了一個Image
作為另一個元素來顯示網格覆蓋父級高度。
這里重要的是你如何為 Constraints 設置 maxHeight
constraints.copy(maxHeight = parentConstraints.maxHeight)
如果您希望網格與項目大小相匹配,那么您應該測量項目的大小
使用rowCount * itemHeight + (rowCount-1)* verticalSpacingInPx
。
constraints.copy(maxHeight = 600f)
例如。
如果您不知道項目的高度,您應該使用 Modifier.onSizeChanged 或在此答案中使用SubcomposeLayout
或Layout
並使用 Text 作為依賴項,我們可以這樣做
@Composable
private fun Sample2() {
val arrayList = remember {
mutableStateListOf<String>().apply {
repeat(40) {
add("Item $it")
}
}
}
val mainComposable = @Composable {
Box(
modifier = Modifier
.shadow(2.dp, RoundedCornerShape(8.dp))
.background(Color.White)
.size(80.dp)
.padding(2.dp)
) {
Text(arrayList[0])
}
}
Column(
modifier = Modifier
.border(4.dp, Color.Green)
.fillMaxSize()
) {
DimensionSubcomposeLayout(
rowCount = 3,
verticalSpacing = 16.dp,
mainContent = {
mainComposable()
}
) { size: Dp ->
LazyColumn {
//other contents
item {
Image(
modifier = Modifier
.height(200.dp)
.fillMaxWidth(),
painter = painterResource(id = R.drawable.landscape2),
contentDescription = null,
contentScale = ContentScale.FillBounds
)
}
item {
LazyHorizontalGrid(
modifier = Modifier
.height(size)
.border(2.dp, Color.Red),
rows = GridCells.Fixed(3),
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
items(arrayList.size) {
Box(
modifier = Modifier
.shadow(2.dp, RoundedCornerShape(8.dp))
.background(Color.White)
.size(80.dp)
.padding(2.dp)
) {
Text(arrayList[it])
}
}
}
}
}
}
}
}
使用文本高度和間距計算 LazyHorizontal Grid 高度的 SubComposeLayout
@Composable
fun DimensionSubcomposeLayout(
modifier: Modifier = Modifier,
rowCount: Int,
verticalSpacing: Dp = 0.dp,
mainContent: @Composable () -> Unit,
dependentContent: @Composable (Dp) -> Unit
) {
val density = LocalDensity.current
val verticalSpacingPx = density.run { verticalSpacing.toPx() }
SubcomposeLayout(
modifier = modifier
) { constraints: Constraints ->
// Subcompose(compose only a section) main content and get Placeable
val mainPlaceable = subcompose(SlotsEnum.Main, mainContent)
.map {
it.measure(constraints)
}
.first()
// Get max width and height of main component
val maxHeight = mainPlaceable.height * rowCount + (rowCount - 1) * verticalSpacingPx
val dpSize = with(density.density) {
maxHeight.toDp()
}
val dependentPlaceable = subcompose(SlotsEnum.Dependent) {
dependentContent(dpSize)
}
.map { measurable: Measurable ->
measurable.measure(constraints)
}
.first()
layout(dependentPlaceable.width, dependentPlaceable.height) {
dependentPlaceable.placeRelative(0, 0)
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.