Reputation: 121
I am rebuilding one of my applications in Jetpack Compose which has a lot of dialogs. Previously I used MaterialAlertDialogBuilder for this, but now I am using the Dialog Composables for richer Dialogs like this:
@Composable
fun FeedbackDialog(context: Context) {
val openDialog by openDialogFeedback
if (openDialog) {
Dialog(onDismissRequest = {openDialogFeedback.value = false}) {
//content here can include texts, drawables and onclick listeners
}
}
}
where openDialogFeedback
is defined as a global variable:
var openDialogFeedback: MutableState<Boolean> = mutableStateOf(false)
And to show the dialog, I just use openDialogFeedback.value = true
The issue is that for every dialog I want to show, I need to create a global variable that stores the state of the dialog. In my case, that amounts to a lot of global variables. I doubt if the approach I am using is correct as this may qualify for memory leaks, apart from excessive memory usage. Also, using the same composable function for every dialog and passing text, drawables and and onclick functions is not feasible due to different designs.
I am new to Jetpack Compose so my approach may be totally wrong. So what is the correct way of showing multiple dialogs in Jetpack Compose?
Upvotes: 2
Views: 2357
Reputation: 67218
There can be many ways to do it. I use a mutableState that accepts values which can be nullable of a data class to show different one time events or show same event on some interaction as
data class DialogEvent(
val type: DialogType,
val message: String
)
enum class DialogType {
RowType, ColumnType
}
Some dialog Composables with different layouts
@Composable
private fun ColumnDialog(
text: String,
onDismissRequest: () -> Unit
) {
Dialog(onDismissRequest = onDismissRequest) {
Row(Modifier.background(Color.Green)) {
Text(text = text)
Text(text = text)
}
}
}
@Composable
private fun RowDialog(
text: String,
onDismissRequest: () -> Unit
) {
Dialog(onDismissRequest = onDismissRequest) {
Row(Modifier.background(Color.Red)) {
Text(text = text)
Text(text = text)
}
}
}
And an event that changes based on user interaction initially null or when dismissed
@Preview
@Composable
private fun DialogTest() {
var dialogEvent by remember {
mutableStateOf<DialogEvent?>(value = null)
}
dialogEvent?.let { event ->
when (event.type) {
DialogType.RowType -> {
RowDialog(text = event.message) {
dialogEvent = null
}
}
DialogType.ColumnType -> {
ColumnDialog(text = event.message) {
dialogEvent = null
}
}
}
}
Column {
Button(onClick = {
dialogEvent = DialogEvent(DialogType.ColumnType, "Column Dialog")
}
) {
Text(text = "Column Dialog")
}
Button(onClick = {
dialogEvent = DialogEvent(DialogType.RowType, "Row Dialog")
}
) {
Text(text = "Row Dialog")
}
}
}
Upvotes: 6