Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jetpack Compose Nested LazyColumn

How do I build this UI in Jetpack Compose? Assuming I will need a lazy column for the filter titles and then another nested lazy column for the actual filters but since the jetpack compose doesn't allow nested lazy column what's the alternative way to build it?

Even if I specify the height for the second or first lazy column the content inside may not fit.

Filter layout

like image 974
Akram Hussain Avatar asked Oct 20 '25 17:10

Akram Hussain


1 Answers

Edit: It is better to use the option suggested by Phil Dukhov, link to comment.

Hacky one: You can hack by adding nested Column. Take a look at the pseudocode:

@Composable
fun Screen(
    items: List<Item>,
) {
    // Here we store each state of expandable item
    val expandStates = remember(items.size) {
        List(items.size) { mutableStateOf(false) }
    }

    LazyColumn {
        itemsIndexed(items, { _, it -> it.key }) { idx, item ->
            ExpandableItem(
                modifier = Modifier.fillMaxWidth(),
                item = item.expandable,
                isExpanded = expandStates[idx].value,
            )
        }
    }
}

@Composable
private fun ExpandableItem(
    item: Item,
    isExpanded: Boolean,
    modifier: Modifier = Modifier,
) {
    Column(modifier = modifier.animateContentSize()) {
        Row(
            modifier = Modifier.height(50.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(modifier = Modifier.weight(1f), text = item.title)
            val icon = if (isExpanded) R.drawable.ic_minus else R.drawable.ic_plus
            Icon(
                modifier = Modifier.padding(horizontal = 16.dp),
                painter = painterResource(icon),
                contentDescription = null
            )
        }
        if (isExpanded) Column {
            item.values.forEach { item ->
                ValueItem(
                    modifier = Modifier.fillMaxWidth(),
                    item = item,
                )
            }
        }
    }
}

@Composable
private fun ValueItem(
    item: Item,
    modifier: Modifier = Modifier,
) {
    Column(modifier = modifier) {
        Row(
            modifier = Modifier
                .height(50.dp)
                .padding(start = 16.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                modifier = Modifier.weight(1f),
                text = item.name,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        }
    }
}

In example above Item represent some abstract content for you specific case.

like image 198
Sky Avatar answered Oct 23 '25 06:10

Sky



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!