One Off the Slack: How Do We Show a Non-Compose Dialog?

Migrating an app to using Compose UI may require you to bridge to non-Compose bits of UI. You might be using an SDK that deals with activities, fragments, and custom views, for example. Or, perhaps you want to use something that already works but has no composable equivalent right now.

Dmitry Suzdalev had the latter scenario:

what is the safe way to show old-style android dialog from Composable function?

For example:

@Composable
fun ScreenContent(state: State) {
  if (state.showDialog) {
    // Need to show MaterialDatePicker here
  }
}

Dmitry wondered about possibly using SideEffect here. Google’s Zach Klippenstein suggested DisposableEffect instead:

if (state.showDialog) {
  DisposableEffect(dialogDetails) {
    // create dialog, call .show()
    onDispose {
      // Dismiss dialog
    }
  }
}

Albert Chang implemented this in an app and offered a more complete implementation:

if (showDialog) {
    val fragmentManager = (LocalContext.current as? FragmentActivity)?.supportFragmentManager
    DisposableEffect(fragmentManager) {
        var datePicker: MaterialDatePicker<*>? = null
        if (fragmentManager != null) {
            datePicker = MaterialDatePicker.Builder.datePicker()
                .setTitleText(title)
                .build()
                .apply {
                    addOnPositiveButtonClickListener {
                        date = it
                    }
                    addOnDismissListener { showDialog = false }
                    show(fragmentManager, javaClass.name)
                }
        }
        onDispose {
            datePicker?.dismiss()
        }
    }
}

Read the original thread in the kotlinlang Slack workspace. Not a member? Join that Slack workspace here!