Search code examples
androidswipeoverlapcomposableexposeddropdownmenu

Disable swipe gesture in child component in Android Jetpack Compose


As mentioned by the title, I want to disable the swipe gestures ExposedDropdownMenuBox in a Composable.

The reason is sometimes, the swipe triggers both Drawer's swipe to open and the ExposedDropdownMenuBox. Specifically, when you swipe on the Dropdown menu title.

How can I swipe over the ExposedDropdownMenuBox to open the Drawer only, not trigger the dropdown menu?

Sample Activity of a Drawer & a DropDown Menu:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyDrawerTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    Body("Android")
                }
            }
        }
    }
}

@Composable
fun Body(name: String) {
    Scaffold(
        drawerContent = {
            Text("Drawer title $name", modifier = Modifier.padding(16.dp))
            Divider()
            // Drawer items
        }
    ) {
        // Screen content
        DropBox()
    }
}

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun DropBox(){
    val options = listOf("Option 1", "Option 2", "Option 3", "Option 4", "Option 5")
    var expanded by remember { mutableStateOf(false) }
    var selectedOptionText by remember { mutableStateOf(options[0]) }

    ExposedDropdownMenuBox(
        expanded = expanded,
        onExpandedChange = {
            expanded = !expanded
        }
    ) {
        TextField(
            readOnly = true,
            value = selectedOptionText,
            onValueChange = { },
            label = { Text("Label") },
            trailingIcon = {
                ExposedDropdownMenuDefaults.TrailingIcon(
                    expanded = expanded
                )
            },
            colors = ExposedDropdownMenuDefaults.textFieldColors()
        )
        ExposedDropdownMenu(
            expanded = expanded,
            onDismissRequest = {
                expanded = false
            }
        ) {
            options.forEach { selectionOption ->
                DropdownMenuItem(
                    onClick = {
                        selectedOptionText = selectionOption
                        expanded = false
                    }
                ) {
                    Text(text = selectionOption)
                }
            }
        }
    }
}

Swipe on the Title of the dropdown menu cause the Drawer open and dropdown menu open at the same time. As shown in the Screenshot

Overlap drawer and dropdown menu


Solution

  • Since Compose 1.4.0-alpha04, the issue seems to be solved, i.e. the app does not open the burger menu while swiping upon the dropdown menu item.

    Before, I had a workaround using menu offset to check if the burger menu is actually in the closed position:

    if (scaffoldState.drawerState.offset.value == HomeScreenVM.closedMenuOffset) { //Perform task if the burger menu is closed}
    

    And closedMenuOffset is a static var

     companion object {
         var closedMenuOffset = 0f
            set(value) {
                if (field > value) field = value
            }
     }