从另一个图表导航到片段,而不是起始目的地

Posted

技术标签:

【中文标题】从另一个图表导航到片段,而不是起始目的地【英文标题】:Navigate to a fragment from another graph without it being the start destination 【发布时间】:2020-05-16 01:05:31 【问题描述】:

在我的第一张图中,我有以下内容:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/firstGraph"
    app:startDestination="@id/listFragment">

    <fragment
        android:id="@+id/listFragment"
        android:name="com.example.ListFragment">

        <action
            android:id="@+id/action_list_to_details"
            app:destination="@id/detailsFragment" />

    </fragment>

    <fragment
        android:id="@+id/detailsFragment"
        android:name="com.example.DetailsFragment">

    </fragment>
</navigation>

在我的第二张图中,我有以下内容:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/secondGraph"
    app:startDestination="@id/dashboardFragment">

    <include app:graph="@navigation/firstGraph" />

    <fragment
        android:id="@+id/dashboardFragment"
        android:name="com.example.DashboardFragment">
        <action
            android:id="@+id/action_dashboard_to_notification"
            app:destination="@id/notificationFragment"/>
    </fragment>

    <fragment
        android:id="@+id/notificationFragment"
        android:name="com.example.NotificationsFragment">

        <action
            android:id="@+id/action_notification_to_details"
            app:destination="@id/firstGraph"/>

    </fragment>
</navigation>

我想直接从“notificationFragment”导航到“detailsFragment”而不是开始目的地,包括第二个图形堆栈

【问题讨论】:

我也有同样的问题。我考虑过删除嵌套图(以一团糟为代价),但即使这样我也做不到,因为我使用的是由图上下文共享的视图模型。 我之前设法通过创建一个“temp” dest 作为图形的开始来使其工作,该图形接收它读取并用于重新导航的参数 - 弹出自身。这可行,但它会破坏共享元素的过渡动画。 我通过复制图表暂时解决了它,我可能分享了您的意见决定不使用它,但它看起来像ios中的故事板一样漂亮的导航方法 【参考方案1】:

根据nested graph documentation:

[嵌套图]还提供了一定程度的封装——嵌套图之外的目的地无法直接访问嵌套图中的任何目的地。

有一个例外,当您是 navigating using a URI 时,有效地深层链接到 任何 目的地:

与使用操作或目标 ID 的导航不同,您可以导航到图表中的任何 URI,而不管目标是否可见。您可以导航到当前图表上的目的地或完全不同图表上的目的地。

因此你可以add an implicit deep link to your graph:

<fragment
    android:id="@+id/detailsFragment"
    android:name="com.example.DetailsFragment">
    <deepLink app:uri="android-app://your.package.name/details" />
</fragment>

然后通过 URI 导航到该目的地:

val uri = Uri.parse("android-app://your.package.name/details")
navController.navigate(uri)

只要&lt;deepLink&gt; 和你传递给navigate 的内容匹配,你的URI 是什么并不重要。您拥有的任何参数都需要在 URL 中进行编码。

【讨论】:

这看起来很有希望,但我想说当参数是一个对象时它会变得很奇怪——因为那时我必须打破对象属性并在 URL 中一个一个地传递。跨度> 此外,deeplink 会创建 backstack:"当嵌套图时,每一层嵌套的起始目的地——即层次结构中每个 元素的起始目的地——是也添加到堆栈中。”。因此,这可能会导致一些奇怪的行为,即用户看到他们没有去过的屏幕。 @FirstOne - 按 URI 导航不会添加任何合成回栈目标。这就是该文档中When navigating using URI, the back stack is not reset. This is unlike other deep link navigation, where the back stack is replaced when navigating. 行的含义。 @AhmadAlselwadi - 是的,这正是我特别提到Any arguments you have would need to be encoded in the URL.时的意思 @FirstOne - 考虑到参数计入您可以放入已保存实例状态的有限数据量(或面临TransactionTooLargeException,特别是因为较新版本的 Android 进一步降低了该限制),在所有情况下,传递标识符都是一种更好的处理方式,而不仅仅是这个特定的情况。

以上是关于从另一个图表导航到片段,而不是起始目的地的主要内容,如果未能解决你的问题,请参考以下文章

Android 目的地片段未出现在导航中

热门从另一个片段导航到主页片段

Android导航组件后退按钮不起作用

BottomNavigation popBackStack() 导航到 startDestination 而不是上一个片段

从另一个片段导航后,ViewPager在返回时不可见

导航到目的地时仅创建一个片段实例(android)