Skip to content

Commit 8d46924

Browse files
authored
Merge pull request #58 from android/dt/dialog-recipe
Add a recipe for creating dialogs
2 parents 6982b0f + 1cb6bb7 commit 8d46924

File tree

4 files changed

+103
-0
lines changed

4 files changed

+103
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ These are the recipes and what they demonstrate.
1212

1313
**Layouts and animations**
1414
- **[Material adaptive](app/src/main/java/com/example/nav3recipes/scenes/materiallistdetail)**: Shows how to use a Material list-detail layout.
15+
- **[Dialog](app/src/main/java/com/example/nav3recipes/dialog)**: Shows how to create a Dialog destination.
1516
- **[Custom Scene](app/src/main/java/com/example/nav3recipes/scenes/twopane)**: Shows how to create a custom layout using a `Scene` and `SceneStrategy` (see video of UI behavior below).
1617
- **[Animations](app/src/main/java/com/example/nav3recipes/animations)**: Override the default animations for all destinations and a single destination.
1718

app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@
6161
android:exported="true"
6262
android:label="@string/app_name"
6363
android:theme="@style/Theme.Nav3Recipes"/>
64+
<activity
65+
android:name=".dialog.DialogActivity"
66+
android:exported="true"
67+
android:theme="@style/Theme.Nav3Recipes"/>
6468
<activity
6569
android:name=".scenes.materiallistdetail.MaterialListDetailActivity"
6670
android:exported="true"

app/src/main/java/com/example/nav3recipes/RecipePickerActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import com.example.nav3recipes.basicdsl.BasicDslActivity
2828
import com.example.nav3recipes.basicsaveable.BasicSaveableActivity
2929
import com.example.nav3recipes.commonui.CommonUiActivity
3030
import com.example.nav3recipes.conditional.ConditionalActivity
31+
import com.example.nav3recipes.dialog.DialogActivity
3132
import com.example.nav3recipes.modular.hilt.ModularActivity
3233
import com.example.nav3recipes.passingarguments.basicviewmodels.BasicViewModelsActivity
3334
import com.example.nav3recipes.passingarguments.injectedviewmodels.InjectedViewModelsActivity
@@ -50,6 +51,7 @@ private val recipes = listOf(
5051
Recipe("Animations", AnimatedActivity::class.java),
5152
Recipe("Conditional navigation", ConditionalActivity::class.java),
5253
Recipe("Common UI", CommonUiActivity::class.java),
54+
Recipe("Dialog", DialogActivity::class.java),
5355
Recipe("Material list-detail layout", MaterialListDetailActivity::class.java),
5456
Recipe("Two pane layout", TwoPaneActivity::class.java),
5557
Recipe("Argument passing to basic ViewModel", BasicViewModelsActivity::class.java),
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.nav3recipes.dialog
18+
19+
import android.os.Bundle
20+
import androidx.activity.ComponentActivity
21+
import androidx.activity.compose.setContent
22+
import androidx.compose.foundation.shape.RoundedCornerShape
23+
import androidx.compose.material3.Button
24+
import androidx.compose.material3.Text
25+
import androidx.compose.runtime.remember
26+
import androidx.compose.ui.Modifier
27+
import androidx.compose.ui.draw.clip
28+
import androidx.compose.ui.unit.dp
29+
import androidx.compose.ui.window.DialogProperties
30+
import androidx.navigation3.runtime.NavKey
31+
import androidx.navigation3.runtime.entry
32+
import androidx.navigation3.runtime.entryProvider
33+
import androidx.navigation3.runtime.rememberNavBackStack
34+
import androidx.navigation3.ui.DialogSceneStrategy
35+
import androidx.navigation3.ui.NavDisplay
36+
import com.example.nav3recipes.content.ContentBlue
37+
import com.example.nav3recipes.content.ContentGreen
38+
import com.example.nav3recipes.ui.setEdgeToEdgeConfig
39+
import kotlinx.serialization.Serializable
40+
41+
/**
42+
* This recipe demonstrates how to create a dialog. It does this by:
43+
*
44+
* - Adding the `DialogSceneStrategy` to the list of strategies used by `NavDisplay`.
45+
* - Adding `DialogSceneStrategy.dialog` to a `NavEntry`'s metadata to indicate that it is a
46+
* dialog. In this case it is applied to the `NavEntry` for `RouteB`.
47+
*
48+
* See also https://developer.android.com/guide/navigation/navigation-3/custom-layouts
49+
*/
50+
51+
@Serializable
52+
private data object RouteA : NavKey
53+
54+
@Serializable
55+
private data class RouteB(val id: String) : NavKey
56+
57+
class DialogActivity : ComponentActivity() {
58+
59+
override fun onCreate(savedInstanceState: Bundle?) {
60+
setEdgeToEdgeConfig()
61+
super.onCreate(savedInstanceState)
62+
setContent {
63+
val backStack = rememberNavBackStack(RouteA)
64+
val dialogStrategy = remember { DialogSceneStrategy<NavKey>() }
65+
66+
NavDisplay(
67+
backStack = backStack,
68+
onBack = { backStack.removeLastOrNull() },
69+
sceneStrategy = dialogStrategy,
70+
entryProvider = entryProvider {
71+
entry<RouteA> {
72+
ContentGreen("Welcome to Nav3") {
73+
Button(onClick = {
74+
backStack.add(RouteB("123"))
75+
}) {
76+
Text("Click to open dialog")
77+
}
78+
}
79+
}
80+
entry<RouteB>(
81+
metadata = DialogSceneStrategy.dialog(
82+
DialogProperties(windowTitle = "Route B dialog")
83+
)
84+
) { key ->
85+
ContentBlue(
86+
title = "Route id: ${key.id}",
87+
modifier = Modifier.clip(
88+
shape = RoundedCornerShape(16.dp)
89+
)
90+
)
91+
}
92+
}
93+
)
94+
}
95+
}
96+
}

0 commit comments

Comments
 (0)