在导航组件中以编程方式管理片段BackStack

问题描述

我正在开发一个使用单个活动 多个片段的项目。我正在使用Jetpack Navigation Components。我可以使用NavGraph,NavHost and NavController进行导航,但是问题是there are multiple situations where I need to move from one fragment to other fragment and vice-versa and require to clear the backstack accordinglyI was managing these using actions in NavGraph 示例-例如,在成功通过身份验证后从SignIn Fragment移至Dashboard Fragment的情况下,已从中删除了SigIn Fragment后栈。另一个示例-在遇到密码问题的情况下从SignIn Fragment移至ForgotPassword Fragment,再次从堆栈中清除现有片段,并清除更多此类情况All the mentioned examples required to generate multiple actions from one fragment to other and vice-versa。使用individual actions中的NavGraph进行管理,将生成Navgraph and Fragments look messed up with multiple actions。它想以编程方式在class files中进行操作。 如何实施?

注意-I know that Navigation components uses the existing FragmentManager and FragmentTransactions。而且我要从Navigation Components中获取任何类或api,以便无需使用backstack就可以轻松管理FragmentManager and FragmentTransaction

注意:- 我知道我可以在类文件中/以编程方式从一个片段导航到另一个片段,而无需使用 view.findNavController().navigate(R.id.Nextfragment)来使用NavGraph,但这不是帮助管理backstack

解决方法

好的,这就是它的工作方式。

在两个overloaded forms中,NavController classpopBackStack() that pops the current Fragment(if available) from the backstack中有一个可用的方法popBackStack(@IdRes int destinationId,boolean inclusive) which takes user specified destination(next_fragment_id) and a boolean which is used as flag for popToInclusive

我做什么-

binding.tvMoveToSignUp.setOnClickListener {
            it.findNavController().apply {
                popBackStack(R.id.signInFragment,true)
                navigate(R.id.signUpFragment)
            }
        }

在上述情况下, I'am first getting the NavController by calling view.findNavController() then popping the current fragment by calling popBackStack(R.id.signInFragment,true) which is SignInFragment 并设置flag popToInclusive to true to pop upto SignInFragmentthen navigating to SignUpFragment calling navigate(R.id.signUpFragment)

,

使用Jetpack Navigation Components的目的是您不需要照顾后备箱。就像过去使用FragmentManager和FragmentTransaction一样。

我要从Navigation Components中获取任何类或api,以便 无需使用FragmentManager和 FragmentTransaction

此声明有矛盾。

导航组件为您提供了在n个片段之间移动的机制,具有您提到的所有选项(例如,使用ID导航,使用安全Args操作,使用NavController.popBackStack(),NavController.navigateUp()等) )。

示例1-例如从SignIn Fragment移至Dashboard Fragment 成功验证后,将SigIn片段从 回栈。

示例2-从中的SignIn片段移至ForgotPassword片段 如果密码有问题,请再次清除退出 来自堆栈的碎片以及更多此类情况

在您的两个示例中,您似乎都具有复杂的结构,但是您正在尝试将每个片段放在单个NavGraph中。

您可以创建具有类似片段流的NestedGraphs,而不是多次弹出。因此,当您从“登录流程”图移至“仪表板片段NevGraph”时。

请通过Design navigation graphs来了解何时需要嵌套图。

binding.tvMoveToSignUp.setOnClickListener {
            it.findNavController().apply {
                popBackStack(R.id.signInFragment,true)
                navigate(R.id.signUpFragment)
            }
        }

您在这里所做的事情以您的方式是正确的,但是我相信这不是最佳的设计模式。考虑任何银行应用程序并使用它测试您的用例。 从开发人员的角度来看,当我可能有超过100个片段时,我也不会记住我将拥有popUp()的所有片段或以inclusive打开的片段。

这是关于NestedGraphs的另一篇好文章。我希望您能理解我要确立的观点。

快乐编码!

,

很简单,转到您的 nav_graph.xml 文件,然后转到您的 action 标签,写入 popUpToInclusive="true" ,然后写 popUpTo="@id/splashScreen" (这里传递那个屏幕的 id ,你想删除它,在我的例子中它是 splashScreen )。检查下面的代码以更好地理解..

    <fragment
        android:id="@+id/splashScreen"
        android:name="com.codingwithjks.firebase.SplashScreen"
        android:label="splash_screen"
        tools:layout="@layout/splash_screen" >
        <action
            android:id="@+id/action_splashScreen_to_showUploads"
            app:destination="@id/showUploads"
            app:popUpToInclusive="true"
            app:popUpTo="@id/splashScreen"
            app:enterAnim="@anim/nav_default_pop_enter_anim" />
    </fragment

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...