使用导航控制器创建两次的片段 [英] Fragment created twice with navigation controller

查看:25
本文介绍了使用导航控制器创建两次的片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在应用中,我们启动了一个持有片段的新 Activity,我们称其为 A.最近添加了导航组件,并且转换遵循导航图.

In the app, we start a new activity holding a fragment, let's call it A. Recently navigation component was added and transitions follow the navigation graph.

所以最初它是由

        navController = findNavController(R.id.nav_host_fragment)
        val graphInflater = navController.navInflater
        val navGraph = graphInflater.inflate(R.navigation.something_graph)

        val startDestination: Int = something

        navGraph.startDestination = startDestination
        navController.setGraph(navGraph, intent.extras)

之后,用户做了一些动作,调用了一个新的片段,比如说片段 B,然后我们需要回到片段 A.

Afterward, the user makes some actions, invokes a new fragment, let's say fragment B, and then we need to get back to fragment A.

目前,这是由

findNavController().navigate(SomethingGraphDirections.actionGlobalNavSomethingFragment(action, destination))

不幸的是,这会导致片段 A(不是活动)作为新实例被调用两次,然后按照类似于 这篇文章.

Unfortunately this causes fragment A (not activity), to be called twice as a new instance, and then delete is called as described similarly to this post.

我可以通过在日志上打印this语句来验证它.

I can verify it by printing on the log this statements.

Activity com.sen.osmo.ui.SomethingActivity@aad8485 onCreate
Fragment SomethingFragment{1c32bd3} (325a1bc9-d922-49ff-8d0a-65e35427d109) id=0x7f0901c8} onCreateView

action
Fragment SomethingFragment{fd9bbac} (eedc20a5-49b1-481c-8045-4cd60c427c78) id=0x7f0901c8} onCreateView
Fragment SomethingFragment{1c32bd3} (325a1bc9-d922-49ff-8d0a-65e35427d109) id=0x7f0901c8} onDestroy

normal end of cycle and actions 

Fragment SomethingFragment{fd9bbac} (eedc20a5-49b1-481c-8045-4cd60c427c78) id=0x7f0901c8} onDestroy
Activity com.sen.osmo.ui.SomethingActivity@aad8485 onDestroy 

尝试使用旧代码而不是 findNavController().navigate 可以稍微解决这个问题.这是

Trying the old code instead of findNavController().navigate solves this issue somewhat. which is

        if (fragmentManager!!.backStackEntryCount > 0) {
            fragmentManager!!.popBackStack()
        } else {
           ...
        }
        fragmentManager!!.beginTransaction().remove(this).commitAllowingStateLoss()

结果是在同一个实例上两次调用 create ,并且没有调用 onDestroy.

The result is on create called twice but on the same instance, and no onDestroy is called.

Activity onCreate com.sen.osmo.ui.SomethingActivity@96035a6
Fragment onCreateView, savedInstance: true SomethingFragment{44b835a} (d5190920-63a8-4356-bf02-41936dd710a5) id=0x7f0901c8}

action
Fragment onCreateView, savedInstance: true SomethingFragment{44b835a} (d5190920-63a8-4356-bf02-41936dd710a5) id=0x7f0901c8}

Fragment onDestroy SomethingFragment{44b835a} (d5190920-63a8-4356-bf02-41936dd710a5) id=0x7f0901c8}
Activity onDestroy com.sen.osmo.ui.SomethingActivity@96035a6

这种方法是否正确?

然而,这是一个现在不推荐使用的方法,我发现我们应该使用

However, this is a deprecated method now and as I found we should use

   requireActivity().supportFragmentManager

但这给出了一个例外

  java.lang.IllegalStateException: Cannot remove Fragment attached to a different FragmentManager.

那么最终我们应该使用什么解决方案?有没有办法使用导航控制器弹出片段 B 以便在不使用导航的情况下返回片段 A?

推荐答案

我终于找到了答案,而不是导航回你想要的片段,你需要从 backstack 弹出它们.这不会创建新实例并且生命周期是正确的.

I finally found the answer, instead of navigating back to the fragment you want, you need to pop them from the backstack. This doesnt create new instances and the lifecycle is correct.

            findNavController().popBackStack(R.id.nav_something_fragment, false)

最后也看到了这个答案,上面说的都是一样的

Finally also saw this answer which says the same

这篇关于使用导航控制器创建两次的片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆