使 LazyColumn 项目与列表中最大的项目一样大

vov*_*ost 6 android android-jetpack-compose

@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)
            )
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

布局预览:

撰写布局预览

我希望项目的宽度与列表中最大项目的宽度相同。

请注意.horizontalScroll(horizontalScrollState),这是为了允许水平滚动。

我想要什么:

理想的布局预览

我需要使用 aLazyColumn但如果我可以使用 aColumn我会这样写:

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)
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

Phi*_*hov 5

  1. 您需要单独计算最宽元素的宽度。您可以通过将包含最宽内容的单元格的不可见副本放置BoxLazyColumn.

    在您的示例中,这很简单 - 只需获取最长的字符串即可。如果在实际项目中您无法决定哪一个内容是最宽的,您有两种选择:

    1.1. 将它们全部放在一起。只有当你的细胞数量有限时你才能做到这一点,

    1.2. 否则,您必须进行一些近似并过滤出您期望最宽的列表。

  2. 由于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)
    )
}
Run Code Online (Sandbox Code Playgroud)

结果: