在 Android 导航中,“对话框目的地”一词是指应用导航图中的目的地,会以对话框窗口的形式叠加在应用界面元素和内容之上。
由于对话框目的地会显示在填充
导航宿主中,有一些关于对话框如何
目的地与您的 NavController
的返回堆栈交互。
对话框可组合项
如需在 Compose 中创建对话框目的地,请使用 dialog()
函数向 NavHost
添加目的地。该函数的行为与 composable
基本相同,只不过它会创建对话框目的地而非托管目的地。
请参考以下示例:
@Serializable
object Home
@Serializable
object Settings
@Composable
fun HomeScreen(onNavigateToSettings: () -> Unit){
Column {
Text("Home")
Button(onClick = onNavigateToSettings){
Text("Open settings")
}
}
}
// This screen will be displayed as a dialog
@Composable
fun SettingsScreen(){
Text("Settings")
// ...
}
@Composable
fun MyApp() {
val navController = rememberNavController()
NavHost(navController, startDestination = Home) {
composable<Home> { HomeScreen(onNavigateToSettings = { navController.navigate(route = Settings) }) }
dialog<Settings> { SettingsScreen() }
}
}
- 起始目的地使用
Home
路由。因为composable()
会将其添加到图表中,它是一个托管目的地。 - 另一个目的地使用
Settings
路由。- 同样,由于
dialog()
会将其添加到图表,因此它是一个对话框, 目标。 - 当用户从
HomeScreen
导航到SettingsScreen
时, 后者出现在HomeScreen
之上。
- 同样,由于
- 虽然
SettingsScreen
本身不包含Dialog
可组合项,但由于它是对话框目的地,NavHost
会在Dialog
中显示它。
对话框目的地会显示在 NavHost
中的上一个目的地之上。使用
当对话框代表应用中需要自己拥有的单独界面时,
生命周期和已保存状态,不依赖于
导航图。如果您想使用对话框显示不太复杂的提示(例如确认),不妨考虑使用 AlertDialog
或相关可组合项。
Kotlin DSL
如果您使用 fragment,同时还使用 Kotlin DSL 创建图,添加对话框目的地与使用 Compose 时的操作非常相似。
思考一下,以下代码段如何亦使用 dialog()
函数来添加使用 fragment 的对话框目的地:
// Define destinations with serializable classes or objects
@Serializable
object Home
@Serializable
object Settings
// Add the graph to the NavController with `createGraph()`.
navController.graph = navController.createGraph(
startDestination = Home
) {
// Associate the home route with the HomeFragment.
fragment<HomeFragment, Home> {
label = "Home"
}
// Define the settings destination as a dialog using DialogFragment.
dialog<SettingsFragment, Settings> {
label = "Settings"
}
}
XML
如果您已有 DialogFragment
,请使用 <dialog>
元素
将该对话框添加到您的导航图,如以下示例所示:
<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/nav_graph"> ... <dialog android:id="@+id/my_dialog_fragment" android:name="androidx.navigation.myapp.MyDialogFragment"> <argument android:name="myarg" android:defaultValue="@null" /> <action android:id="@+id/myaction" app:destination="@+id/another_destination"/> </dialog> ... </navigation>