对话框目的地

在 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() }
    }
}
  1. 起始目的地使用 Home 路由。因为 composable() 会将其添加到图表中,它是一个托管目的地。
  2. 另一个目的地使用 Settings 路由。
    • 同样,由于 dialog() 会将其添加到图表,因此它是一个对话框, 目标。
    • 当用户从 HomeScreen 导航到 SettingsScreen 时, 后者出现在 HomeScreen 之上。
  3. 虽然 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>