Multi-Select Dropdown Menu no Jetpack Compose

Tempo de leitura: < 1 minute

Olá a todos, peguem uma xícara de café ☕ e vamos ver como criar um menu multi-select dropdown no Jetpack Compose.

 

Vamos começar criando o SelectableDropdownMenu, que recebe uma lista de nomes como parâmetro. Depois disso, precisamos criar uma variável que mantenha o estado expandido do dropdown e uma lista que saiba quais nomes estão selecionados.

@Composable
fun SelectableDropdownMenu(names: List<String>) {
    var isExpanded by remember {
        mutableStateOf(false)
    }

    val selectedNames = remember {
        mutableStateListOf<String>()
    }
}

Agora usaremos o ExposedDropdownMenuBox. Ele será ancorado ao TextField. Isso garantirá que ela não apareça aleatoriamente na tela.

ExposedDropdownMenuBox(
    expanded = isExpanded,
    onExpandedChange = { isExpanded = it }
) {
    TextField(
        value = selectedNames.joinToString(", "),
        onValueChange = {},
        placeholder = {
            Text(text = "Select a name")
        },
        readOnly = true, // Makes the TextField clickable
        trailingIcon = {
            ExposedDropdownMenuDefaults.TrailingIcon(expanded = isExpanded)
        },
        colors = ExposedDropdownMenuDefaults.textFieldColors(),
        modifier = Modifier.menuAnchor() // Needed to anchor the dropdown menu
    )

    // ...
}

Abaixo do TextField, criaremos o ExposedDropdownMenu, que contém uma lista de DropdownMenuItem. Esses itens suspensos exibirão os nomes. Quando um nome for selecionado, uma marca de seleção aparecerá à frente dele.

ExposedDropdownMenuBox(
    expanded = isExpanded,
    onExpandedChange = { isExpanded = it }
) {
    // TextField

    ExposedDropdownMenu(
        expanded = isExpanded,
        onDismissRequest = { isExpanded = false }
    ) {
        names.forEach { name ->
            AnimatedContent(
                targetState = selectedNames.contains(name),
                label = "Animate the selected item"
            ) { isSelected ->
                if (isSelected) {
                    DropdownMenuItem(
                        text = {
                            Text(text = name)
                        },
                        onClick = {
                            selectedNames.remove(name)
                        },
                        leadingIcon = {
                            Icon(
                                imageVector = Icons.Rounded.Check,
                                contentDescription = null
                            )
                        }
                    )
                } else {
                    DropdownMenuItem(
                        text = {
                            Text(text = name)
                        },
                        onClick = {
                            selectedNames.add(name)
                        },
                    )
                }
            }
        }
    }
}

Para obter as atualizações mais recentes, siga-me e assine o boletim informativo.