A dialog can have a rather complex ui, acting more like a floating screen rather than a typical AlertDialog. Therefore it can be desired to let the dialog have its own ViewModel
and being able to navigate to it. When using the jetpack compose navigation artifact the code indicates that only one composable is shown at any time inside the NavHost
.
Is there a way to navigate to a dialog that is overlaid onto the current ui? This would be in line with how we can navigate to fragment dialogs. Thanks.
If you want to use the Navigation component with Compose, you have two options: Define a navigation graph with the Navigation component for fragments. Define a navigation graph with a NavHost in Compose using Compose destinations. This is possible only if all of the screens in the navigation graph are composables.
Creating a new Jetpack Compose app To create a new app, open Android Studio, select File > New > New Project, and in the wizard select Empty Compose Activity. Then, click Finish, and a new Jetpack Compose project will be created.
Keep in mind that the existing View-based toolkit had 10 years of time to mature so practically it makes sense we should at least expect around 3–4 years for Jetpack Compose to catch up & become stable so as to be adopted by teams on a larger scale.
A LazyColumn is a vertically scrolling list that only composes and lays out the currently visible items. It's similar to a Recyclerview in the classic Android View system.
Then I would like to introduce you to Compose Destinations — a code generating library that tries to improve navigation in this new Jetpack Compose world. Let's start by looking at some code of how we would define a navigation graph in Compose: You define your Composables: You add some kind of sealed class or enum that contains all your routes:
Step 1: First we will create separate file for custom dialog named as CustomDialog.kt In that file we will placed below code Step 2: In this step we will create one button in launch dialog and print whatever user is going to add in that dialog. Paste below code in our MainActivity.kt That's it, you are done with Custom dialog using jetpack compose.
The Navigation component provides support for Jetpack Compose applications. You can navigate between composables while taking advantage of the Navigation component’s infrastructure and features. Note: If you are not familiar with Compose, review the Jetpack Compose resources before continuing.
The NavHost links the NavController with a navigation graph that specifies the composable destinations that you should be able to navigate between. As you navigate between composables, the content of the NavHost is automatically recomposed. Each composable destination in your navigation graph is associated with a route.
Aha. This is now a feature in compose navigation version 2.4.0-alpha04
From the release notes
The NavHost of the navigation-compose artifact now supports dialog destinations in addition to composable destinations. These dialog destinations will each be shown within a Composable Dialog, floating above the current composable destination.
val navController = rememberNavController()
Scaffold { innerPadding ->
NavHost(navController, "home", Modifier.padding(innerPadding)) {
composable("home") {
// This content fills the area provided to the NavHost
HomeScreen()
}
dialog("detail_dialog") {
// This content will be automatically added to a Dialog() composable
// and appear above the HomeScreen or other composable destinations
DetailDialogContent()
}
}
}
Example:
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = Screen.Menu.route
) {
// some other screens here: composable(...) { ... }
dialog(
route = "exit_dialog",
dialogProperties = DialogProperties(
dismissOnBackPress = true,
dismissOnClickOutside = true,
)
) {
Box(modifier = Modifier.width(280.dp)) {
Box(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(10.dp))
.background(DialogBorder)
.padding(bottom = 3.dp)
.clip(RoundedCornerShape(10.dp))
.background(DialogBackground),
) {
Column {
Column(
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = stringResource(id = R.string.text_dialog_exit_title),
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
color = Color.Black
)
Text(
text = stringResource(id = R.string.text_dialog_exit_description),
fontSize = 16.sp,
fontWeight = FontWeight.Normal,
textAlign = TextAlign.Center,
color = Color.Black
)
}
Divider(color = DialogBorder)
Row(modifier = Modifier.height(IntrinsicSize.Min)) {
Box(
modifier = Modifier
.weight(1f)
.clickable {
// dismiss dialog
navController.popBackStack()
}
.padding(horizontal = 16.dp, vertical = 8.dp),
contentAlignment = Alignment.Center
) {
Text(
text = stringResource(id = R.string.button_cancel),
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
color = Color.Black
)
}
Box(
modifier = Modifier
.fillMaxHeight()
.width(1.dp)
.background(DialogBorder),
)
Box(
modifier = Modifier
.weight(1f)
.clickable {
// go back to home other screen
navController.popBackStack(
route = "home_screen",
inclusive = false
)
}
.padding(horizontal = 16.dp, vertical = 8.dp),
contentAlignment = Alignment.Center
) {
Text(
text = stringResource(id = R.string.button_ok),
fontSize = 16.sp,
fontWeight = FontWeight.Normal,
color = Color.Black
)
}
}
}
}
}
}
}
It's a feature request: https://issuetracker.google.com/issues/179608120 You can star it so perhaps we'll increase it's priority
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With