简体   繁体   中英

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)
            )
        }
    }
}

Preview of the layout:

撰写布局预览

I'd like to have the items width be the same as the largest item in the list.

Notice the .horizontalScroll(horizontalScrollState) , this is to allow horizontal scrolling.

What I'd like:

理想的布局预览

I need to use a LazyColumn but if I could use a Column I'd write it this way:

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)
        )
    }
}

This is not possible when horizontal srolling is enabled.

Regular Modifier.fillMaxWidth can't work inside the scrolling horizontally layouts as the items are measured with Constraints.Infinity as the constraints for the main axis.

If you want your Column solution to work, you need to place it inside another contain (like a Box) and apply horizontal scrolling to the parent. Scrolling on the Column itself needs to be removed:

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. You need to calculate width of the widest element separately. You can do it by placing an invisible copy of you cell with widest content in a Box along with LazyColumn .

    In your sample it's easy - just get the longest string. If in the real project you can't decide which of contents is gonna be the widest one, you have two options:

    1.1. Place all of them one on top of each other. You can do it only if you have some limited number of cells,

    1.2. Otherwise you have to made some approximation and filter a short list of the ones you expect to be the widest ones.

  2. Because of horizontalScroll maxWidth constraint is infinity, you have to pass calculated width manually. You can get it with 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)
    )
}

Result:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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