如何以编程方式更改导航图的起始目的地?

新手上路,请多包涵

基本上,我有以下导航图:

在此处输入图像描述

我想在到达后立即将导航图中的起点更改为 fragment 2 (为了防止在按下后退按钮时返回到 fragment 1 就像使用初始屏幕一样)。

这是我的代码:

 navGraph = navController.getGraph();
navGraph.setStartDestination(R.id.fragment2);
navController.setGraph(navGraph);

但是,显然它不起作用并且在按下后退按钮后它会回到 fragment 1

我做错了吗?还有其他解决方案吗?

原文由 Shynline 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 837
2 个回答

更新:

当你有这样的导航图时:

 <fragment
    android:id="@+id/firstFragment"
    android:name="com.appname.package.FirstFragment" >
    <action
        android:id="@+id/action_firstFragment_to_secondFragment"
        app:destination="@id/secondFragment" />
</fragment>

<fragment
    android:id="@+id/secondFragment"
    android:name="com.appname.package.SecondFragment"/>

并且您想导航到第二个片段并使其成为图表的根,请指定下一个 NavOptions

 NavOptions navOptions = new NavOptions.Builder()
        .setPopUpTo(R.id.firstFragment, true)
        .build();

并将它们用于导航:

 Navigation.findNavController(view).navigate(R.id.action_firstFragment_to_secondFragment, bundle, navOptions);

setPopUpTo(int destinationId, boolean inclusive) - 在导航之前弹出到给定的目的地。这会从返回堆栈中弹出所有不匹配的目标,直到找到该目标。

destinationId - 要弹出的目的地,清除所有中间目的地。

inclusive true 也可以从后面的堆栈中弹出给定的目标。

选择:

 <fragment
    android:id="@+id/firstFragment"
    android:name="com.appname.package.FirstFragment" >
<action
    android:id="@+id/action_firstFragment_to_secondFragment"
    app:destination="@id/secondFragment"
    app:popUpTo="@+id/firstFragment"
    app:popUpToInclusive="true" />
</fragment>

<fragment
    android:id="@+id/secondFragment"
    android:name="com.appname.package.SecondFragment"/>

然后在您的代码上:

 findNavController(fragment).navigate(
    FirstFragmentDirections.actionFirstFragmentToSecondFragment())

旧答案

已弃用--- 中的动作和相关 API 的 NavOptions clearTask 属性已被弃用。

来源: https ://developer.android.com/jetpack/docs/release-notes

如果您想将根片段更改为 fragment 2 (例如在 fragment 2 您将退出应用程序),您应该将下一个属性放入您的 actiondestination

 app:clearTask="true"

实际上,它看起来像下一个方式:

 <fragment
    android:id="@+id/firstFragment"
    android:name="com.appname.package.FirstFragment"
    android:label="fragment_first" >
    <action
        android:id="@+id/action_firstFragment_to_secondFragment"
        app:destination="@id/secondFragment"
        app:clearTask="true" />
</fragment>

<fragment
    android:id="@+id/secondFragment"
    android:name="com.appname.package.SecondFragment"
    android:label="fragment_second"/>

我已将 app:clearTask="true" 添加到操作中。

现在,当您执行从 fragment 1fragment 2 的导航时,请使用以下代码:

 Navigation.findNavController(view)
        .navigate(R.id.action_firstFragment_to_secondFragment);

原文由 Oleksii Denysenko 发布,翻译遵循 CC BY-SA 4.0 许可协议

对于那些拥有与此类似内容的导航 xml 文件的人:

 <?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/mobile_navigation"
    app:startDestination="@+id/nav_home">

    <fragment
        android:id="@+id/nav_home"
        android:name="HomeFragment"
        android:label="@string/menu_home"
        tools:layout="@layout/fragment_home" />

    <fragment
        android:id="@+id/nav_users"
        android:name="UsersFragment"
        android:label="@string/users"
        tools:layout="@layout/fragment_users" />

    <fragment
        android:id="@+id/nav_settings"
        android:name="SettingsFragment"
        android:label="@string/settings"
        tools:layout="@layout/fragment_settings" />
</navigation>

假设当前打开的片段是主片段,并且您想要导航到用户片段,因为只需调用要从导航控制器导航到导航方法的元素的 setOnClickListener,类似于此代码:

 yourElement.setOnClickListener {
  view.findNavController().navigate(R.id.nav_users)
}

这将使应用程序导航到另一个片段,并且还将处理工具栏中的标题。

原文由 Juan Ricardo 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题