如何使用新的导航架构组件禁用某些片段的导航中的 UP?
How to disable UP in Navigation for some fragment with the new Navigation Architecture Component?
我正在试用新的 Navigation Architecture Component,但我不知道该怎么做:
我有 1 个 Activity(主要Activity)+ 3 个片段:
- SplashFragment(主页)
- 主要片段
- SignUpFragment
我想使用 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
:
我正在试用新的 Navigation Architecture Component,但我不知道该怎么做:
我有 1 个 Activity(主要Activity)+ 3 个片段:
- SplashFragment(主页)
- 主要片段
- SignUpFragment
我想使用 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
: