嵌套导航时,导航的返回堆栈丢失

Navigation's back stack is lost when navigation is nested

我有一个看起来像这样的导航

Frag1 -> Frag2 -> Frag3

Frag2 里面有一个 NavHostFragment 有自己的导航

InnerFrag1 -> InnerFrag2

如果我这样做

  1. 导航到 Frag2
  2. 导航到 Frag2
  3. 内的 InnerFrag2
  4. 导航到 Frag3
  5. 返回

然后我会在 Frag2 中看到 InnerFrag2,当我正常按回时,我会在 Frag2 中从 InnerFrag2 转到 InnerFrag1,但是现在它会变成 Frag1

这是我在里面的导航处理 Frag2


    private val backPressedCallback = OnBackPressedCallback {
        navHostFragment.navController.navigateUp()
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        requireActivity().addOnBackPressedCallback(backPressedCallback)
    }

    override fun onDestroyView() {
        activity?.removeOnBackPressedCallback(backPressedCallback)
        super.onDestroyView()
    }

    private val navHostFragment: NavHostFragment
        get() = childFragmentManager.findFragmentById(R.id.innerNavHostFragment) as NavHostFragment

当返回到 Frag2 时,导航主机中的片段是正确的,但向后导航会远离 Frag2,因为内部导航主机的返回堆栈丢失。我可以以某种方式坚持它或以其他方式修复它吗?

编辑: 实际上从 Frag3Frag2 我在里面看到 InnerFrag1,两者看起来很像,这就是为什么要回去在这一点上让我回到 Frag1

EDIT2: 我发现了我的问题,我从 onViewCreated 中的代码膨胀 Frag2s 导航,像这样

    val navHostFragment = (frag2NavHostFragment as? NavHostFragment) ?: return
    val inflater = navHostFragment.navController.navInflater
    val graph = inflater.inflate(navigationId)
    navHostFragment.navController.graph = graph

在 xml 中设置它使其工作,我仍然需要以某种方式从代码中设置它,Frag2 根据其参数选择要使用的导航

现在我的问题从 Navigation's back stack is lost 变为 How to preserve NavHostFragment's state when settings it's graph from code

您现在可以处理 onBackPress 片段。在您的片段中,只需将其添加到 onViewCreated 方法中。

val navController = Navigation.findNavController(view)
        requireActivity().onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                navController.popBackStack(R.id.fragmentWhereYouWantToGo, false)
            }
        })

我还会检查 app:popUpToapp:popUpToInclusivesingleTop XML 属性到 Frag2

中的片段

稍微研究了一下,原来的问题没有多大意义,我会删除它,但它得到了 2 个赞成票¯\_(ツ)_/¯

我通过在扩充图形之前添加一个检查来解决我的问题,这样 NavHostFragment 的图形只有在它还没有图形时才会被设置。

    try {
        navHostFragment.navController.graph
    } catch (e: IllegalStateException) {
        val inflater = navHostFragment.navController.navInflater
        val graph = inflater.inflate(navigationId)
        navHostFragment.navController.graph = graph
    }

NavController.getGraph 不会 return null,而是抛出 IllegalStateException,因此奇怪的检查