Home > Mobile >  Is there a way to filter the exposed dropdown menu options depending on the value of another exposed
Is there a way to filter the exposed dropdown menu options depending on the value of another exposed

Time:06-29

So for example lets say I wanted the user to select a car on a car selection screen. The user would first select the car make they want from the first dropdown and depending on what make they choose the second menu would update and would show all the possible models for that specific make.

CodePudding user response:

You just need to recompose your sub ExposedDropDownMenu with new data. I add a sample

@Composable
private fun SubSelectionComposable() {
    val list = listOf("SelectionA", "SelectionB", "SelectionC")
    val subListA = listOf("SubA1", "SubA2", "SubA3")
    val subListB = listOf("SubB1", "SubB2", "SubB3")
    val subListC = listOf("SubC1", "SubC2", "SubC3")


    var mainSelection by remember { mutableStateOf(-1) }
    var subSelection by remember { mutableStateOf(-1) }

    val subList = remember(mainSelection) {
        when(mainSelection){
            1-> subListB
            2-> subListC
            else-> subListA
        }
    }

    ExposedSelectionMenu(
        modifier =Modifier,
        index = mainSelection,
        options = list,
        title = "Main Selection",
        onSelected = {
            mainSelection = it
            subSelection = 0
        }
    )

    ExposedSelectionMenu(
        modifier =Modifier,
        index = subSelection,
        options = subList,
        title = "Sub Selection",
        onSelected = {
            subSelection = it

        }
    )
}

I set indexes -1 as default, it can be 0 too. Purpose of setting -1 is to know whether user picked anything or not.

Result

enter image description here

This my ExposedMenu, you can have your own

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ExposedSelectionMenu(
    modifier: Modifier = Modifier,
    index: Int,
    title: String? = null,
    textStyle: TextStyle = TextStyle(
        fontWeight = FontWeight.W600,
        fontSize = 14.sp
    ),
    colors: TextFieldColors = ExposedDropdownMenuDefaults.textFieldColors(
        containerColor = Color.Transparent,
        focusedIndicatorColor = Color.Transparent,
        unfocusedIndicatorColor = Color.Transparent,
        disabledIndicatorColor = Color.Transparent
    ),
    options: List<String>,
    onSelected: (Int) -> Unit
) {

    var expanded by remember { mutableStateOf(false) }
    var selectedOptionText = options[index.coerceAtLeast(0)]

    ExposedDropdownMenuBox(
        modifier = modifier,
        expanded = expanded,
        onExpandedChange = {
            expanded = !expanded
        }
    ) {
        TextField(
            modifier = modifier,
            readOnly = true,
            value = selectedOptionText,
            onValueChange = { },
            label = {
                title?.let {
                    Text(it)
                }
            },
            trailingIcon = {
                ExposedDropdownMenuDefaults.TrailingIcon(
                    expanded = expanded
                )
            },
            colors = colors,
            textStyle = textStyle
        )
        ExposedDropdownMenu(
            expanded = expanded,
            onDismissRequest = {
                expanded = false

            }
        ) {
            options.forEachIndexed { index: Int, selectionOption: String ->
                DropdownMenuItem(
                    onClick = {
                        selectedOptionText = selectionOption
                        expanded = false
                        onSelected(index)
                    },
                    text = {
                        Text(text = selectionOption)
                    }
                )
            }
        }
    }
}
  • Related