DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Expandable Lists and Accordion Patterns in Compose

Expandable lists and accordion patterns help organize content and reduce screen clutter. Jetpack Compose makes these patterns easy to implement.

Basic Expandable Item

@Composable
fun ExpandableItem(
    title: String,
    content: String,
    modifier: Modifier = Modifier
) {
    var expanded by remember { mutableStateOf(false) }

    Column(modifier = modifier) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .clickable { expanded = !expanded }
                .padding(16.dp),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(title, style = MaterialTheme.typography.titleMedium)
            Icon(
                imageVector = if (expanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
                contentDescription = null
            )
        }

        AnimatedVisibility(expanded) {
            Text(content, modifier = Modifier.padding(16.dp))
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Accordion List

Multiple expandable items where only one is open:

@Composable
fun AccordionList(items: List<Pair<String, String>>) {
    var expandedIndex by remember { mutableStateOf(-1) }

    LazyColumn {
        itemsIndexed(items) { index, (title, content) ->
            ExpandableItem(
                title = title,
                content = content,
                expanded = expandedIndex == index,
                onToggle = { expandedIndex = if (expandedIndex == index) -1 else index }
            )
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Tree View with Nesting

@Composable
fun TreeNode(
    node: Node,
    level: Int = 0
) {
    var expanded by remember { mutableStateOf(false) }

    Column(modifier = Modifier.padding(start = (level * 16).dp)) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .clickable { expanded = !expanded }
                .padding(8.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            if (node.children.isNotEmpty()) {
                Icon(
                    imageVector = if (expanded) Icons.Default.KeyboardArrowDown
                                 else Icons.Default.KeyboardArrowRight,
                    contentDescription = null
                )
            }
            Text(node.title)
        }

        AnimatedVisibility(expanded) {
            Column {
                node.children.forEach { child ->
                    TreeNode(child, level + 1)
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Expandable content patterns significantly improve information architecture and user experience.


8 Android app templates available on Gumroad

Top comments (0)