Search code examples
androidkotlinandroid-jetpack-compose

How to handle dismiss requests from Dialog launched from a Composable passed as a variable


I want to create a composable to handle generic settings which display a Dialog (e.g. to replace the EditTextPreference and ListPreference of Androidx Preference API). The idea is that this GenericSettingWithDialog accepts in input the Composable handling the Dialog content:

@Composable
fun GenericSettingWithDialog (
    name: String,
    state: State<String>,
    dialogContent: @Composable ()-> Unit
) {
    var isDialogShown by remember {
        mutableStateOf(false)
    }
    if (isDialogShown) {
        Dialog(onDismissRequest = {
            isDialogShown = false
        }) {
            dialogContent()
        }
    }
    // setting row launching the dialog, with title and graphics
}

Unfortunately, this implementation is not able to handle dialog dismiss requests coming from the dialog itself, like when clicking the Confirm button.

I am working on the possibility of using Kotlin's Function literals with receiver as shown in this answer: Jetpack Compose function with lambda () -> Unit, but still unclear how.


Solution

  • If you want to dismiss dialog on the a event of dialogContent then we can pass a lamda function in the dialogContent: @Composable ()-> Unit like below.

    Updated GenericSettingWithDialog code

    @Composable
    fun GenericSettingWithDialog (
        name: String,
        state: State<String>,
        dialogContent: @Composable ( onDismiss: (() -> Unit)? )-> Unit
    ) {
        var isDialogShown by remember {
            mutableStateOf(true)
        }
        if (isDialogShown) {
            Dialog(onDismissRequest = {
                isDialogShown = false
            }) {
                dialogContent(){
                    isDialogShown = false
                }
            }
        }
        // setting row launching the dialog, with title and graphics
    }
    

    While using above function follow as below

    GenericSettingWithDialog("abc",str){onDismiss->
            Box(modifier = Modifier
                .size(250.dp)
                .background(Grey1)){
                Box (modifier = Modifier
                    .size(50.dp)
                    .background(Color.Red)
                    .clickable {
                        onDismiss?.invoke()
                    }){
    
                }
            }
        }
    

    Here onDismiss is called when you want to dismiss dialog from dialogContent

    Cheers!!