Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
780 views
in Technique[技术] by (71.8m points)

android - How to navigate back from fragments inside NavHostFragment of ViewPager2?

What is the proper way of navigating back from nested fragments of ViewPager2?

Despite using app:defaultNavHost="true"with FragmentContainerView pressing back button while in a nested fragment of a page calls Activity's back press instead of navigating back to previous fragment.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

As per the Create a NavHostFragment documentation, app:defaultNavHost="true" calls setPrimaryNavigationFragment() when the Fragment is first added - it is setPrimaryNavigationFragment() that routes back button press events to that fragment automatically.

In a ViewPager2 though, it is the ViewPager2 that is responsible for creating and adding the Fragment. Since every level of the Fragment hierarchy needs to be the primary navigation fragment, adding a child fragment via XML still doesn't solve the missing link: that the Fragment in the ViewPager2 needs to be the primary navigation fragment.

Therefore, you need to hook into the callbacks for when a Fragment is made the active Fragment and call setPrimaryNavigationFragment(). ViewPager2 1.1.0-alpha01 adds exactly this API in the FragmentTransactionCallback, specifically, the onFragmentMaxLifecyclePreUpdated(), which is called whenever the Lifecycle state of a Fragment is changed: when it is changed to RESUMED, that Fragment is now the active fragment and should become the primary navigation Fragment as part of the onPost callback.

private class Adapter(parentFragment: Fragment) : FragmentStateAdapter(parentFragment) {
    init {
        // Add a FragmentTransactionCallback to handle changing
        // the primary navigation fragment
        registerFragmentTransactionCallback(object : FragmentTransactionCallback() {
            override fun onFragmentMaxLifecyclePreUpdated(
                    fragment: Fragment,
                    maxLifecycleState: Lifecycle.State
            ) = if (maxLifecycleState == Lifecycle.State.RESUMED) {
                // This fragment is becoming the active Fragment - set it to
                // the primary navigation fragment in the OnPostEventListener
                OnPostEventListener {
                    fragment.parentFragmentManager.commitNow {
                        setPrimaryNavigationFragment(fragment)
                    }
                }
            } else {
                super.onFragmentMaxLifecyclePreUpdated(fragment, maxLifecycleState)
            }
        })
    }

    // The rest of your FragmentStateAdapter...
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...