如何使用导航架构组件从 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 您正在寻找的正确片段。