我正在以编程方式为应用程序的每个功能插入NavHostFragment
。每个NavHostFragment
都有自己的导航图。 Dagger通过使用特定于每个功能的FragmentFactory
来提供它们。这是具有MVVM体系结构的单一活动结构。
回购:https://github.com/mitchtabian/DaggerMultiFeature/tree/nav-component-backstack-bug
检出分支“ nav-component-backstack-bug”。
导航到图形中时,片段不会添加到Backstack中。添加的唯一片段是最近访问的那个片段。 因此堆栈大小始终保持不变。
最初,我认为这是因为我没有将FragmentFactory
设置为ChildFragmentManager
,但这并没有任何改变。有关相关代码,请参见下面的代码段。或签出项目并运行它。我有日志从ChildFragmentManager
和SupportFragmentManager
打印出当前在后堆栈中的片段。两者的大小均为1。
Feature1NavHostFragment.kt
这是自定义NavHostFragment
之一。伴随对象中的create()
函数是我创建它们的方式。
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
的示例。
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
这是我导航到图中其他片段的一个示例。
btn_go_next.setOnClickListener {
findNavController().navigate(R.id.action_feature1MainFragment_to_feature1NextFragment)
}
就像我说的那样,在每个片段中,我都为ChildFragmentManager
和SupportFragmentManager
打印后退堆栈。两者的大小均为1。就像在导航到图中而不是添加到堆栈中一样,片段被替换了。
无论如何,感谢您阅读本文,我将不胜感激。
答案 0 :(得分:2)
看起来对我来说是个误会(对我来说也是个错误)。
如果您循环浏览childFragmentManager
中的片段,由于某种原因,它只会显示最上面的片段。
示例
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
}
但是,如果您像这样打印后退尺寸,您将得到正确的答案。
val navHostFragment = supportFragmentManager
.findFragmentByTag(getString(R.string.NavHostFragmentTag)) as NavHostFragment
val backstackCount = navHostFragment.childFragmentManager.backStackEntryCount
println("backstack count: $backstackCount")
最终,这种误解使我相信片段没有被添加到后台。一切都很好。