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...
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…