android-jetpack-composeoverlaydisabled-input

How to disable interactions of all Components at once in Jetpack Compose


I have a Column (not full screen) containing a few components like TextFiled, Chip, etc.. and There's a Submit button and I need to disable all component interactions (Click, Type) once this button is clicked.

Is there any proper and simple way to fulfill this requirement without disabling each Component one by one?

Eg. Display transparent overlay


Solution

  • If you add a sibling Box composable and set click listener on it based on a flag you will be able to disable every interaction.

    enter image description here

    @Composable
    fun TouchDisable(
        modifier: Modifier = Modifier,
        disableTouch: Boolean,
        content: @Composable () -> Unit
    ) {
        val focusManager = LocalFocusManager.current
    
        LaunchedEffect(disableTouch) {
            if (disableTouch) {
                focusManager.clearFocus()
            }
        }
    
        Box(
            modifier = modifier
        ) {
            content()
            Box(
                modifier = Modifier.matchParentSize().then(
                    if (disableTouch) {
                        Modifier.clickable(
                            interactionSource = remember { MutableInteractionSource() },
                            indication = null,
                            onClick = {}
                        )
                    } else {
                        Modifier
                    }
                )
            )
        }
    }
    

    Demo

    @Preview
    @Composable
    private fun TouchTest() {
        Column {
    
            var disableTouch by remember { mutableStateOf(true) }
            var text by remember { mutableStateOf("Text") }
    
            Button(
                onClick = {
                    disableTouch = disableTouch.not()
                }
            ) {
                Text("Disabled: $disableTouch")
            }
    
            TouchDisable(
                disableTouch = disableTouch,
                modifier = Modifier.fillMaxWidth().height(200.dp).border(2.dp, Color.Red)
            ) {
                Column {
                    Button(
                        onClick = {}
                    ) {
                        Text("Button1")
                    }
    
                    Button(
                        onClick = {}
                    ) {
                        Text("Button2")
                    }
    
                    TextField(
                        text,
                        onValueChange = { text = it }
                    )
                }
            }
        }
    }