繁体   English   中英

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

[英]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)
        )
    }
}
  1. 您需要单独计算最宽元素的宽度。 您可以通过将内容最广泛的单元格的不可见副本与LazyColumn一起放置在Box中来实现。

    在您的示例中很容易 - 只需获得最长的字符串。 如果在实际项目中您无法确定哪个内容将是最广泛的内容,您有两种选择:

    1.1。 将它们全部放在一起。 只有在细胞数量有限的情况下才能做到这一点,

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

  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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM