如何使用导航架构组件从 ViewPager 页面片段访问主机片段
How to access the host fragment from ViewPager page fragment using Navigation Architecture Components
我有一个项目要迁移到 Navigation Architecture Components。
在迁移之前,我有一个 activity,它有一个托管 ViewPager
的片段;我可以通过引用我在片段事务中设置的主机片段标记从 ViewPager
适配器片段访问此片段中的方法:
MyFragment fragment = (MyFragment ) ((MyActivity) requireActivity())
.getSupportFragmentManager().findFragmentByTag("fragment_tag");
fragment.someMethodInMyFragment();
下面是欺骗部分迁移的图,以及我需要通过黄色箭头访问的内容:
在导航组件中,我没有找到 to set a tag 到承载 ViewPager
的目标片段的机会,因此我可以像以前一样通过标记访问它。此外,ViewPager
适配器片段不是导航组件的一部分。
我尝试了什么:在 ViewPager
适配器片段中:
尝试 1
MyFragment fragment = (MyFragment) getParentFragment(); // This returns the navigation host fragment. So ClassCastException is raised
fragment.someMethodInMyFragment();
尝试 2
MyFragment fragment = (MyFragment) requireActivity().getSupportFragmentManager()
.findFragmentById(R.id.myFragment); // id of myFragment in the nav graph.
fragment.someMethodInMyFragment(); // fragment is null
更新:
发布ViewPager
适配器
public class PageFragmentPagerAdapter extends FragmentStatePagerAdapter {
public PageFragmentPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
return MyPagerFragment.newInstance(position);
}
@Override
public int getCount() {
return 10;
}
}
然后我在 MyFragment
中设置了 ViewPager,如下所示
public class MyFragment extends Fragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewPager viewPager = view.findViewById(R.id.viewpager);
PageFragmentPagerAdapter adapter = new PageFragmentPagerAdapter(requireActivity()
.getSupportFragmentManager());
viewPager.setAdapter(adapter);
}
您的问题是您使用 requireActivity().getSupportFragmentManager()
作为适配器的 FragmentManager
。
相反,对于完全包含在另一个片段中的片段,您应该始终使用 getChildFragmentManager()
- 您会注意到,在配置更改或进程死亡和重新创建的情况下,这是恢复每个片段状态所必需的正确。
当您使用子 FragmentManager 时,requireParentFragment()
将 return 您正在寻找的正确片段。
我有一个项目要迁移到 Navigation Architecture Components。
在迁移之前,我有一个 activity,它有一个托管 ViewPager
的片段;我可以通过引用我在片段事务中设置的主机片段标记从 ViewPager
适配器片段访问此片段中的方法:
MyFragment fragment = (MyFragment ) ((MyActivity) requireActivity())
.getSupportFragmentManager().findFragmentByTag("fragment_tag");
fragment.someMethodInMyFragment();
下面是欺骗部分迁移的图,以及我需要通过黄色箭头访问的内容:
在导航组件中,我没有找到 to set a tag 到承载 ViewPager
的目标片段的机会,因此我可以像以前一样通过标记访问它。此外,ViewPager
适配器片段不是导航组件的一部分。
我尝试了什么:在 ViewPager
适配器片段中:
尝试 1
MyFragment fragment = (MyFragment) getParentFragment(); // This returns the navigation host fragment. So ClassCastException is raised
fragment.someMethodInMyFragment();
尝试 2
MyFragment fragment = (MyFragment) requireActivity().getSupportFragmentManager()
.findFragmentById(R.id.myFragment); // id of myFragment in the nav graph.
fragment.someMethodInMyFragment(); // fragment is null
更新:
发布ViewPager
适配器
public class PageFragmentPagerAdapter extends FragmentStatePagerAdapter {
public PageFragmentPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
return MyPagerFragment.newInstance(position);
}
@Override
public int getCount() {
return 10;
}
}
然后我在 MyFragment
中设置了 ViewPager,如下所示
public class MyFragment extends Fragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewPager viewPager = view.findViewById(R.id.viewpager);
PageFragmentPagerAdapter adapter = new PageFragmentPagerAdapter(requireActivity()
.getSupportFragmentManager());
viewPager.setAdapter(adapter);
}
您的问题是您使用 requireActivity().getSupportFragmentManager()
作为适配器的 FragmentManager
。
相反,对于完全包含在另一个片段中的片段,您应该始终使用 getChildFragmentManager()
- 您会注意到,在配置更改或进程死亡和重新创建的情况下,这是恢复每个片段状态所必需的正确。
当您使用子 FragmentManager 时,requireParentFragment()
将 return 您正在寻找的正确片段。