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

如何解决在导航组件中以编程方式管理片段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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-