Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Dialog as navigation destination with jetpack compose

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.

like image 524
Moritz Avatar asked May 05 '21 07:05

Moritz


People also ask

How do you use navigation in jetpack compose?

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.

How do you make dialog in jetpack?

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.

Is jetpack compose mature enough?

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.

What is LazyColumn in jetpack compose?

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.

Can compose destinations improve navigation in jetpack compose?

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:

How to create a custom dialog using jetpack compose?

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.

What is the navigation component used for?

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.

How do I navigate between composable destinations?

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.


3 Answers

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()
        }
    }
}
like image 71
nwagu Avatar answered Oct 20 '22 06:10

nwagu


Example:

enter image description here

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
                            )
                        }
                    }
                }
            }
        }
    }
}
like image 2
Mike Avatar answered Oct 20 '22 06:10

Mike


It's a feature request: https://issuetracker.google.com/issues/179608120 You can star it so perhaps we'll increase it's priority

like image 1
Damir Mihaljinec Avatar answered Oct 20 '22 07:10

Damir Mihaljinec