使用导航控制器创建两次的片段 [英] Fragment created twice with navigation controller
问题描述
在应用中,我们启动了一个持有片段的新 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屋!