如何使用新的导航架构组件禁用某些片段的导航中的 UP?

How to disable UP in Navigation for some fragment with the new Navigation Architecture Component?

我正在试用新的 Navigation Architecture Component,但我不知道该怎么做:

我有 1 个 Activity(主要Activity)+ 3 个片段:

我想使用 SplashFragment 来确定我是否应该导航到 MainFragment 或 SignUpFragment,但是一旦它到达这 2 个中的任何一个,您应该无法返回到 SplashFragment。我如何使用新的导航组件做到这一点?

我在调用 navigate(R.id.action_xxx) 之前和之后都尝试了 popBackStack,但它们都不起作用(这是有道理的:在它没有任何东西可以弹出之前;在它关闭刚刚添加的片段之后) .这是否意味着唯一的方法是覆盖 onBackPress 以拦截它并确保 navigateUp 在这些情况下不会被调用?

谢谢!

警告:clearTask 已被弃用,并将在未来的版本中删除,不确定解决方案是什么。请暂时关注this issue以保持最新


哦,10分钟后终于找到了秘钥:使用clearTask

我只需将 app:clearTask="true" 添加到该特定操作,或使用 .navigate(R.id.actionXXXX, null, NavOptions.Builder().setClearTask(true).build()),即可完成。只需确保将它添加到 SplashFragment 的所有子项(在本例中,包括 MainFragment 和 SignUpFragment)。

这在 alpha05 版本中对我有用。在操作标签中添加 app:popUpTo="@id/nav_graph"(在您的 nav_graph.xml 文件中)。 这里“@id/nav_graph 是我的图形的 ID,也称为根。

<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/nav_graph"
app:startDestination="@id/startFragment">
.......
<action
android:id="@+id/action_startFragment_to_homeFragment"
app:destination="@id/homeFragment" 
app:popUpTo="@id/nav_graph"/>
.......

您也可以在设计选项卡中执行此操作:- select "SplashFragment" 和 select 您要更改的操作,然后为 [=17= 选择 "root" ]

首先,将属性 app:popUpTo='your_nav_graph_id'app:popUpToInclusive="true" 添加到操作标签。

<fragment
    android:id="@+id/signInFragment"
    android:name="com.glee.incog2.android.fragment.SignInFragment"
    android:label="fragment_sign_in"
    tools:layout="@layout/fragment_sign_in" >
    <action
        android:id="@+id/action_signInFragment_to_usersFragment"
        app:destination="@id/usersFragment"
        app:launchSingleTop="true"
        app:popUpTo="@+id/main_nav_graph"
        app:popUpToInclusive="true" />
</fragment>

其次,导航到目的地,使用上述操作作为参数。

findNavController(fragment).navigate(SignInFragmentDirections.actionSignInFragmentToUserNameFragment())

注意:如果您使用方法 navigate(@IdRes int resId) 进行导航,您将无法获得所需的结果。因此,我使用方法 navigate(@NonNull NavDirections directions).

对于任何想纯粹在代码中做到这一点的人:

Navigation.findNavController(v)
.navigate(R.id.action_splashFragment_to_userProfileFragment2, null, 
new NavOptions.Builder().setPopUpTo(R.id.splashFragment, true).build())

因此,如果您有初始片段和主片段,并且不想在主片段之后返回初始片段,则可以使用下面的方法实现此

<fragment
     android:id="@+id/splashFragment"
     android:name="com.example.youappname.views.SplashFragment"
     android:label="fragment_splash"
     tools:layout="@layout/fragment_splash">
     <action
         android:id="@+id/action_splashFragment_to_mainFragment"
         app:destination="@id/mainFragment"
         app:popUpTo="@id/splashFragment"
         app:popUpToInclusive="true"/>
</fragment>

在你的 Kotlin Splash 片段中:

private lateinit var navController: NavController

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      super.onViewCreated(view, savedInstanceState)

      navController = Navigation.findNavController(view)

}

private fun navigateToMainFrag() {
      navController.navigate(R.id.action_splashFragment_to_mainFragment)
}

现在,当您按下后退按钮时,它会关闭应用程序而不是显示启动画面

示例解决方案是在 fragment/navigation 的 Owner Activity 上添加一个 onBackPressedDispatcher:

https://developer.android.com/guide/navigation/navigation-custom-back#implement_custom_back_navigation