[英]Make LazyColumn items be as large as the largest item in the list
@Composable
fun PreviewLayout() {
fun getRandomString(length: Int): String {
val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
return (1..length)
.map { allowedChars.random() }
.joinToString("")
}
val horizontalScrollState = rememberScrollState()
LazyColumn(
modifier = Modifier
.background(Color.Blue)
.fillMaxHeight()
.wrapContentWidth()
.horizontalScroll(horizontalScrollState)
) {
items(5) { index ->
Text(
text = getRandomString((index + 1) * 4).uppercase(),
color = Color.Black,
fontSize = 16.sp,
modifier = Modifier
.padding(8.dp)
.background(Color.Yellow)
)
}
}
}
布局预览:
我想让项目宽度与列表中最大的项目相同。
注意.horizontalScroll(horizontalScrollState)
,这是为了允许水平滚动。
我想要什么:
我需要使用LazyColumn
但如果我可以使用Column
我会这样写:
Column(
modifier = Modifier
.background(Color.Blue)
.horizontalScroll(horizontalScrollState)
.fillMaxHeight()
.width(IntrinsicSize.Min)
) {
repeat(5) { index ->
Text(
text = getRandomString((index + 1) * 4).uppercase(),
color = Color.Black,
fontSize = 16.sp,
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
.background(Color.Yellow)
)
}
}
当启用水平滚动时,这是不可能的。
常规 Modifier.fillMaxWidth 不能在水平滚动布局内工作,因为项目是使用 Constraints.Infinity 作为主轴的约束来测量的。
如果您希望您的 Column 解决方案起作用,您需要将它放在另一个包含(如 Box)中并将水平滚动应用于父级。 需要删除滚动列本身:
Box(
modifier = Modifier
.requiredWidth(250.dp)
.fillMaxHeight()
.horizontalScroll(rememberScrollState())
) {
Column(
modifier = Modifier
.background(Color.Blue)
.fillMaxHeight()
.width(IntrinsicSize.Min)
) {
repeat(5) { index ->
Text(
text = getRandomString((index + 1) * 40).uppercase(),
color = Color.Black,
fontSize = 16.sp,
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
.background(Color.Yellow)
)
}
}
}
Column(
modifier = Modifier
.background(Color.Blue)
.horizontalScroll(horizontalScrollState)
.fillMaxHeight()
.width(IntrinsicSize.Min)
) {
repeat(5) { index ->
Text(
text = getRandomString((index + 1) * 4).uppercase(),
color = Color.Black,
fontSize = 16.sp,
modifier = Modifier
.padding(8.dp)
.width(//*TODO pass here device width*//)
.background(Color.Yellow)
)
}
}
您需要单独计算最宽元素的宽度。 您可以通过将内容最广泛的单元格的不可见副本与LazyColumn
一起放置在Box
中来实现。
在您的示例中很容易 - 只需获得最长的字符串。 如果在实际项目中您无法确定哪个内容将是最广泛的内容,您有两种选择:
1.1。 将它们全部放在一起。 只有在细胞数量有限的情况下才能做到这一点,
1.2. 否则,您必须进行一些近似并过滤出您期望最广泛的列表。
由于horizo horizontalScroll
maxWidth
约束为无穷大,您必须手动传递计算出的宽度。 您可以使用onSizeChanged
获得它:
@Composable
fun TestScreen(
) {
fun getRandomString(length: Int): String {
val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
return (1..length)
.map { allowedChars.random() }
.joinToString("")
}
val items = remember {
List(30) { index ->
getRandomString((index + 1) * 4).uppercase()
}
}
val maxLengthItem = remember(items) {
items.maxByOrNull { it.length }
}
val (maxLengthItemWidthDp, setMaxLengthItemWidthDp) = remember {
mutableStateOf<Dp?>(null)
}
val horizontalScrollState = rememberScrollState()
Box(
Modifier
.background(Color.Blue)
.horizontalScroll(horizontalScrollState)
) {
LazyColumn(
Modifier.fillMaxWidth()
) {
items(items) { item ->
Cell(
item,
modifier = if (maxLengthItemWidthDp != null) {
Modifier.width(maxLengthItemWidthDp)
} else {
Modifier
}
)
}
}
if (maxLengthItem != null) {
val density = LocalDensity.current
Cell(
maxLengthItem,
modifier = Modifier
.requiredWidthIn(max = Dp.Infinity)
.onSizeChanged {
setMaxLengthItemWidthDp(with(density) { it.width.toDp() })
}
.alpha(0f)
)
}
}
}
@Composable
fun Cell(
item: String,
modifier: Modifier,
) {
Text(
text = item,
color = Color.Black,
fontSize = 16.sp,
modifier = modifier
.padding(8.dp)
.background(Color.Yellow)
)
}
结果:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.