使用导航组件未将片段添加到后堆栈 [英] Fragments not added to backstack using Navigation Components
问题描述
我正在以编程方式为应用程序的每个功能插入NavHostFragment
.每个NavHostFragment
都有其自己的导航图. Dagger通过使用特定于每个功能的FragmentFactory
来提供它们.这是具有MVVM体系结构的单一活动结构.
I'm programmatically inserting a NavHostFragment
for each feature of the app. Each NavHostFragment
has it's own Navigation Graph. Dagger is providing them by using a FragmentFactory
specific to each feature. It's a Single Activity structure with MVVM architecture.
回购: https://github.com/mitchtabian/DaggerMultiFeature/tree/nav-component-backstack-bug
检出分支"nav-component-backstack-bug".
导航到图形中时,片段不会添加到Backstack中.添加的唯一片段是最近访问的那个片段. 因此堆栈大小始终保持不变.
When navigating into the graph the fragments are not being added to the backstack. The only fragment that's added is whichever one has most recently been visited. So the stack size always stays at one.
最初,我认为这是因为我没有将FragmentFactory
设置为ChildFragmentManager
,但这并没有任何改变.有关相关代码,请参见下面的代码段.或签出项目并运行它.我有日志从ChildFragmentManager
和SupportFragmentManager
打印出当前在后堆栈中的片段.两者的大小均为1.
Originally I thought it was because I wasn't setting the FragmentFactory
to the ChildFragmentManager
but that doesn't change anything. See the code snippets below for the relevant code. Or checkout the project and run it. I have logs printing out the fragments currently in the backstack from the ChildFragmentManager
and also the SupportFragmentManager
. Both have a constant size of 1.
Feature1NavHostFragment.kt
这是自定义NavHostFragment
的其中之一.伴随对象中的create()
函数是我创建它们的方式.
This is one of the custom NavHostFragment
's. The create()
function in the companion object is how I create them.
class Feature1NavHostFragment
@Inject
constructor(
private val feature1FragmentFactory: Feature1FragmentFactory
): NavHostFragment(){
override fun onAttach(context: Context) {
((activity?.application) as BaseApplication)
.getAppComponent()
.feature1Component()
.create()
.inject(this)
childFragmentManager.fragmentFactory = feature1FragmentFactory
super.onAttach(context)
}
companion object{
const val KEY_GRAPH_ID = "android-support-nav:fragment:graphId"
@JvmStatic
fun create(
feature1FragmentFactory: Feature1FragmentFactory,
@NavigationRes graphId: Int = 0
): Feature1NavHostFragment{
var bundle: Bundle? = null
if(graphId != 0){
bundle = Bundle()
bundle.putInt(KEY_GRAPH_ID, graphId)
}
val result = Feature1NavHostFragment(feature1FragmentFactory)
if(bundle != null){
result.arguments = bundle
}
return result
}
}
}
MainActivity.kt
这是我如何在MainActivity中创建NavHostFragment
的示例.
This is an example of how I create the NavHostFragment
's in MainActivity.
val newNavHostFragment = Feature1NavHostFragment.create(
getFeature1FragmentFactory(),
graphId
)
supportFragmentManager.beginTransaction()
.replace(
R.id.main_nav_host_container,
newNavHostFragment,
getString(R.string.NavHostFragmentTag)
)
.setPrimaryNavigationFragment(newNavHostFragment)
.commit()
Feature1MainFragment.kt
这是我导航到图中其他片段的一个示例.
And here is an example of how I'm navigating to other fragments in the graph.
btn_go_next.setOnClickListener {
findNavController().navigate(R.id.action_feature1MainFragment_to_feature1NextFragment)
}
摘要
就像我说的那样,在每个片段中,我都为ChildFragmentManager
和SupportFragmentManager
都打印后退堆栈.两者的大小均为1.就像在我导航到图中而不是添加到堆栈中一样,片段被替换了.
Summary
Like I said, in every fragment I'm printing the backstack for both the ChildFragmentManager
and the SupportFragmentManager
. Both have a constant size of one. It's as if the fragments are being replaced as I navigate into the graph instead of added to the stack.
无论如何,感谢您阅读本文,我将不胜感激.
Anyways, thanks for reading this and I would appreciate any insights.
推荐答案
对我来说似乎是一个误解(对我来说也是一个错误).
Looks like a misunderstanding on my part (and a bug, also on my part).
如果您循环浏览childFragmentManager
中的片段,由于某种原因,它只会显示最上面的片段.
If you loop through the fragments in the childFragmentManager
it only ever shows the top-most fragment for some reason.
示例
val navHostFragment = supportFragmentManager
.findFragmentByTag(getString(R.string.NavHostFragmentTag)) as NavHostFragment
val fragments = navHostFragment.childFragmentManager.fragments
for(fragment in fragments){
// Only prints a single fragment, no matter the backstack size
}
但是,如果您像这样打印后退尺寸,您将得到正确的答案.
However, if you print the backstack size like this, you will get the correct answer.
val navHostFragment = supportFragmentManager
.findFragmentByTag(getString(R.string.NavHostFragmentTag)) as NavHostFragment
val backstackCount = navHostFragment.childFragmentManager.backStackEntryCount
println("backstack count: $backstackCount")
最终,这种误解使我相信这些碎片没有被添加到后台.一切都很好.
At the end of the day this misunderstanding caused me to believe the fragments were not being added to the backstack. All is good.
这篇关于使用导航组件未将片段添加到后堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!