Fragments not added to backstack using Navigation Components

陌路散爱 提交于 2020-08-19 04:49:23

问题


Information:

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.

Repo: https://github.com/mitchtabian/DaggerMultiFeature/tree/nav-component-backstack-bug

checkout the branch "nav-component-backstack-bug".


The Problem

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.

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

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

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)
}


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.


回答1:


Looks like a misunderstanding on my part (and a bug, also on my part).

If you loop through the fragments in the childFragmentManager it only ever shows the top-most fragment for some reason.

Example

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.



来源:https://stackoverflow.com/questions/59775946/fragments-not-added-to-backstack-using-navigation-components

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!