导航组件:从片段导航到活动时如何清除返回堆栈?

时间:2021-07-13 00:02:16

标签: kotlin android-activity android-navigation

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

我非常了解导航 xml 上的 popUptopopUpToInclusivelaunchSingleTop 属性。当从 FRAGMENT 导航到 ACTIVITY 时,它们只是 NOT 应用(即使它们仍然出现在导航 xml 中)。我尝试了数十种不同的解决方案,过去 3 天我一直在寻找答案!

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

但是解决方案本身太丑了,我不愿意自己去实现。重新启动相同的活动并在为我执行此操作时接受闪烁的黑屏似乎不是一种选择。

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

总结问题:当使用导航组件FRAGMENT_Login(示例)到ACTIVITY_home时,我想完全清除后台堆栈。知道如何实现这一目标吗?

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

片段起源

   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)
    }

上面的代码导致 Activity 被多次创建/销毁/重新创建,根据我的测试,我认为这是我正在使用的 2 个 Intent 标志的组合。如果我只使用 Intent.FLAG_ACTIVITY_CLEAR_TASK 或只使用 Intent.FLAG_ACTIVITY_NEW_TASK,那么我不会遇到问题,但也不会清除 backstack,因此当用户按下 Activity 上的后退按钮时,他会被带回 片段

我可以在原始片段上调用 ​​requireActivity().finish() 但这似乎也是一个黑客。我觉得我所缺少的只是关于使用这些标志的一些细节......

任何帮助将不胜感激! <3

1 个答案:

答案 0 :(得分:0)

我成功了。上面的示例正常工作,唯一的问题是 REMOVE POPUPTOPOPUPTOINCLUSIVELAUNCHSINGLETOP 属性来自与此 Fragment-Activity 转换相关的 ACTION即使这些属性具有值“FALSE”。如果您只是使用导航 xml 的设计将它们关闭,它们仍将存在并切换为 false。 移除它们

谢谢大家。