如何从 FragmentPagerAdapter 返回多个片段

Posted

技术标签:

【中文标题】如何从 FragmentPagerAdapter 返回多个片段【英文标题】:How to return multiple fragments from FragmentPagerAdapter 【发布时间】:2018-10-13 17:17:02 【问题描述】:

如果我将TabLayoutFragmentPagerAdapter 一起使用,则被覆盖的函数getItem(int position) 只返回一个片段。如果屏幕较大,我希望退回 2 个片段。 我该怎么做?应该将这两个片段包装成一个片段并改用它还是有更好的解决方案?

FragmentPagerAdapter:

public class SectionsPagerAdapter extends FragmentPagerAdapter 

    public SectionsPagerAdapter(FragmentManager fm) 
        super(fm);
    

    @Override
    public Fragment getItem(int position) 
        switch (position) 
            case 0: //Ingredients
                return IngredientsFragment.newInstance(mRecipe);
            case 1: // Details
            
                // TODO Here instead of DetailFragment I want to return
                // two fragments called DetailFragment and StepFragment.
                return DetailFragment.newInstance(mRecipe);
            
            default:
                throw new RuntimeException(this.toString() + " Wrong fragment!");
        
    

然后在我的 Activity onCreate:

    @Override
    protected void onCreate(Bundle savedInstanceState) 

        // Initializing, etc.

        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
        mViewPager.setAdapter(mSectionsPagerAdapter);

        TabLayout tabLayout = findViewById(R.id.tabs);
        mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
    

【问题讨论】:

我认为返回一个包裹另外两个的片段是明智的解决方案 【参考方案1】:

我认为您在这里没有太大的回旋余地。

这两个选项是唯一的:

    您将返回一个带有两个嵌套片段(包装片段)的片段 您正在返回两个片段,每个片段都锚定到自己的选项卡上。

如果您希望两个片段出现在 ViewPager 的单个页面上,您别无选择,只能将它们包装起来。 否则会在这两个片段之间滑动,就像它们完全不同一样,即不相关。

【讨论】:

【参考方案2】:

好的,我设法使用Fragment 解决了这个问题,该Fragment 由其他两个片段组成。 只是不要忘记在这种情况下FragmentManager 对象应该填充getChildFragmentManager() 才能正常工作。 更多信息请查看我的 BakingApp 项目DetailStepWideScreenFragment.java

GitHub Repos

片段包装器:

public class DetailStepWideScreenFragment extends Fragment 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        View view = inflater.inflate(R.layout.fragment_detail_step_wide_screen, container, false);

        // I added the fragments here. StepFragment can be replaced using
        // replaceStepFragment function.
        DetailFragment detailFragment = DetailFragment.newInstance(mRecipe);
        StepFragment stepFragment = StepFragment.newInstance(mRecipe, mStepId);
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.add(R.id.fl_detail_fragment_wide_screen, detailFragment);
        transaction.add(R.id.fl_step_fragment_wide_screen, stepFragment);
        transaction.commit();

        return view;
    

    public void replaceStepFragment(String stepId) 
        mStepId = stepId;
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        StepFragment stepFragment = StepFragment.newInstance(mRecipe, mStepId);
        transaction.replace(R.id.fl_step_fragment_wide_screen, stepFragment);
        transaction.commit();
    

PagerAdapter:

public class SectionsPagerAdapter extends FragmentPagerAdapter 
    private DetailStepWideScreenFragment currentFragment;

    public SectionsPagerAdapter(FragmentManager fm) 
        super(fm);
        currentFragment = null;
    

    @Override
    public Fragment getItem(int position) 
        switch (position) 
            case 0: //Ingredients
                return IngredientsFragment.newInstance(mRecipe);
            case 1: // Details
            
                // Show base on screen size.
                if (mIsLargeScreen) 
                    DetailStepWideScreenFragment detailStepWideScreenFragment = DetailStepWideScreenFragment.newInstance(mRecipe, "0");
                    currentFragment = detailStepWideScreenFragment;
                    return detailStepWideScreenFragment;
                 else 
                    return DetailFragment.newInstance(mRecipe);
                
            
            default:
                throw new RuntimeException(this.toString() + " Wrong fragment!");
        
    

    @Override
    public int getCount()  return 2; 

    public DetailStepWideScreenFragment getCurrentFragment() 
        return currentFragment;
    


【讨论】:

以上是关于如何从 FragmentPagerAdapter 返回多个片段的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能从 FragmentPagerAdapter 分离片段?

FragmentPagerAdapter 在调用 notifyDataSetChanged 后不会从 0 开始位置

使用 FragmentPagerAdapter 时如何获取现有片段

如何刷新 FragmentPagerAdapter 的片段?

如何在 PagerAdapter 中返回多个片段(不是 FragmentPagerAdapter)

如何在 fragmentPagerAdapter 中调用 getItem(int position)?