Hi, which is the best and simplest approach to par...
# compose
p
Hi, which is the best and simplest approach to parametrize the message to a message style Dialog? Should it be done by a remember state variable that also will be used to know if the dialog must be displayed? Specially I ask this because that dialog can be called a lot of times to display various messages. Also I have another Dialog, this time is a confirmation Dialog. Should I have another different remember state value to determine which kind of dialog must be displayed? Thank you.
m
Honestly, i would create a data class to represent the dialog parameters as a whole, along with a wrapper to keep it in a state object And when you want to show it, you simply have to set the state to something non null, and when you want to hide it, set it to null. This is pretty much a simplified version of how Scaffold provides the snackbar (see the rememberScaffoldState function if you want to dig into it)
Here's a very simple example i whipped up.
Copy code
data class DialogButtonParameters(
    val text: String,
    val onClick: () -> Unit,
)

data class DialogParameters(
    val title: String,
    val confirmButton: DialogButtonParameters?,
    val dismissButton: DialogButtonParameters?,
)

class DialogHostState {
    internal var currentParameters by mutableStateOf<DialogParameters?>(null)

    fun showDialog(parameters: DialogParameters) {
        currentParameters = parameters
    }

    fun hideDialog() {
        currentParameters = null
    }
}

@Composable
fun rememberDialogHostState() =
    remember {
        DialogHostState()
    }


@Composable
fun DialogScaffold(
    state: DialogHostState = rememberDialogHostState(),
    content: @Composable (DialogHostState) -> Unit,
) {
    state.currentParameters?.let { params ->
        AlertDialog(
            onDismissRequest = { state.hideDialog() },
            title = {
                Text(text = params.title)
            },
            confirmButton = {
                params.confirmButton?.let { button ->
                    TextButton(onClick = { button.onClick() }) {
                        Text(text = button.text)
                    }
                }

            },
            dismissButton = {
                params.dismissButton?.let { button ->
                    TextButton(onClick = { button.onClick() }) {
                        Text(text = button.text)
                    }
                }

            },
        )
    }
    content(state)
}


@Composable
@Preview
fun DialogScaffoldPreview() {
    val state = rememberDialogHostState()

    DialogScaffold(state = state) {
        Box(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp)
        ) {
            Button(
                onClick = {
                    state.showDialog(
                        DialogParameters(
                            title = "Hello There",
                            confirmButton = DialogButtonParameters("OK") {
                                state.hideDialog()
                            },
                            dismissButton = null
                        )
                    )
                }
            ) {
                Text(text = "Show Dialog")
            }
        }
    }
}
p
@mattinger Hi thank you very much, have you tried to compile your code? it gives me some compilation errors
for example
ype 'MutableState<DialogParameters?>' has no method 'getValue(DialogHostState, KProperty<*>)' and thus it cannot serve as a delegate
Type 'MutableState<DialogParameters?>' has no method 'setValue(DialogHostState, KProperty<*>, [Error type: Error delegation type for
value-parameter params: [Error type: Cannot infer a lambda parameter type]
value-parameter button: [Error type: Cannot infer a lambda parameter type
OK I managed to solve them, but it seems to be too much complex, I mean, does not exist a simpler way to do it? It's extremely easy without compose, can't believe compose does not offer a simpler way to achieve this.
Also, the dialog is not being displayed if I call your function
I'm trying it in compose-desktop, compose multiplatform, if it helps
m
I have not tried compose desktop. The compile issue you had was with imports, and that happens when you use “by” with remembered state. To my knowledge there’s not any kind of built in way to do dialogs i this manner. To be honest, this is a fairly trivial implementation when you compare it to something like, say how snackbar is implemented in Scaffold.