提问者:小点点

导航组件:从碎片导航到活动时,如何清除后堆栈?


在将其标记为重复之前,请务必阅读完整的问题。

我很清楚导航xml上的popUpto、popUpToPlus sive和LaunchSingleTop属性。当从碎片导航到活动时,它们根本不适用(即使它们仍然出现在导航xml中)。我已经尝试了几十种不同的解决方案,在过去的3天里,我正在寻找答案!

让你们知道,这是迄今为止唯一实际有效的解决方案:https://stackoverflow.com/a/59795636/6952763

但解决方案本身是如此丑陋,以至于我不愿意自己实施。重新开始同样的活动,并在为我做这件事时接受闪烁的黑屏,这似乎不是一个选择。

我从一个良好的工作解决方案中得到的最接近的是 https://stackoverflow.com/a/63566415/6952763 它基于 https://stackoverflow.com/a/63169732/6952763 但出于某种原因,当将Intent.FLAG_ACTIVITY_CLEAR_TASK的组合与目标活动的结果一起添加时Intent.FLAG_ACTIVITY_NEW_TASK要多次创建/销毁/重新创建(大约 8 次)。在片段之间导航时很容易实现它。只有我上面提到的 xml 参数已经完成了这项工作。这里的问题是从片段到活动,这让我头疼:D

总结一下问题:我想在使用导航组件从FRAGMENT_Login(示例)到ACTIVITY_home时完全清除backstack。知道如何实现这一点吗?

到目前为止,我的代码是这样的:

碎片来源

   private fun proceedToHome(user: UserEntity?){
        if(user != null && user.id != 0L){
            val direction = LoginFragmentDirections.actionLoginToMainHostActivity(user.id)
            val extras = ActivityNavigator.Extras.Builder()
                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                .build()
            val navOptions = NavOptions.Builder()
                .setLaunchSingleTop(true)
                .build()
            findNavController().navigate(direction.actionId, direction.arguments, navOptions, extras)
        }
    }

活动目的地:

   override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val mBinding = ActivityMainHostBinding.inflate(layoutInflater)
        setContentView(mBinding.root)
        
        navController = (supportFragmentManager.findFragmentById(R.id.activity_main_host_content) as NavHostFragment).navController
        navController.setGraph(R.navigation.main_host_navigation, intent.extras)

        mBinding.activityMainHostNavigationView.setupWithNavController(navController)
    }

上面的代码导致活动被多次创建/销毁/重新创建,根据我的测试,我认为这是我使用的两个意图标志的组合。如果我只使用<代码>意图。FLAG_ACTIVITY_CLEAR_TASK或仅< code >意图。FLAG_ACTIVITY_NEW_TASK然后我没有得到问题,但也没有清除backstack,所以当用户按下活动上的back按钮时,他被带回片段。

我可以在原始片段上调用requireActivity().finish(),但这似乎也是一个破解。我觉得我所缺少的只是关于这些旗帜使用的一些细节。。。

任何帮助都将不胜感激!


共1个答案

匿名用户

我让它工作了。上面的示例工作正常,唯一的问题是从与片段-活动转换相关的操作中删除POPUPTO、POPUPTOINCLUSIVE和LAUNCHSINGLETOP属性,即使这些属性的值为“FALSE”。如果您只是使用导航xml的设计来关闭它们,它们将仍然存在并被切换为false。移除它们。

谢谢大家。