什么是从ViewPager2的嵌套片段中导航回来的正确方法?
尽管在
尽管在
FragmentContainerView
中使用了app:defaultNavHost="true"
,但在页面的嵌套片段中按下返回按钮会调用Activity的返回按键,而不会导航回以前的片段。FragmentContainerView
中使用了app:defaultNavHost="true"
,但在页面的嵌套片段中按下返回按钮会调用Activity的返回按键,而不会导航回以前的片段。app:defaultNavHost="true"
在首次添加Fragment时调用setPrimaryNavigationFragment()
。因此,会自动将后退按钮事件路由到该Fragment。ViewPager2
中,它是负责创建和添加Fragment的。由于每个Fragment层级都需要成为主要导航Fragment,因此通过XML添加子Fragment仍然无法解决缺失的链接:即ViewPager2中的Fragment需要成为主要导航Fragment。setPrimaryNavigationFragment()
。 ViewPager2 1.1.0-alpha01 在FragmentTransactionCallback
中增加了这个API,具体而言,就是onFragmentMaxLifecyclePreUpdated()
,每当Fragment的生命周期状态被更改时都会调用:当它被更改为RESUMED
时,该Fragment现在是活动Fragment,并且应该成为onPost
回调的主要导航Fragment。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...
}
以下是@ianhanniballake答案的Java版本(是的,我还没有使用kotlin - 我需要彻底了解Java才能学习其他内容)。 我还没有对此进行单元测试,但它“可以工作”...
public class ViewPagerAdapter extends FragmentStateAdapter {
public ViewPagerAdapter(@NonNull FragmentManager fragmentManager,
@NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
registerFragmentTransactionCallback(new FragmentTransactionCallback() {
@NonNull
@Override
public OnPostEventListener onFragmentMaxLifecyclePreUpdated(@NonNull Fragment fragmentArg,
@NonNull Lifecycle.State maxLifecycleState) {
if (maxLifecycleState == Lifecycle.State.RESUMED) {
return () -> fragmentArg.getParentFragmentManager().beginTransaction()
.setPrimaryNavigationFragment(fragmentArg).commitNow();
} else {
return super.onFragmentMaxLifecyclePreUpdated(fragmentArg, maxLifecycleState);
}
}
});
}
// remainder of your FragmentStateAdapter here
}
FragmentStateAdapter
中,所以不得不将它们放到其NavHostFragments
中。 - Thracianapp:defaultNavHost="true"
,则NavHostFragment可以正常工作,否则将无法正常工作。此外,当ViewPager2
本身位于NavHostFragment
中时,您应该为父级和页面NavHostFragments都设置默认导航为true。 - Thracian