Search code examples
androidandroid-fragmentsandroid-tablayoutfragmentpageradapter

How to return multiple fragments from FragmentPagerAdapter


If I use a TabLayout with FragmentPagerAdapter, the overridden function getItem(int position) just return one fragment. In case of lager screen I would like to have 2 fragments to be returned. How can I do it? should wrap these 2 fragments into one fragment and use that instead or is there any better solution?

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!");
        }
    }

And then in my 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));
    }

Solution

  • OK I managed to solve the problem using a Fragment consist of two other fragments as children. Just do not forget in this case the FragmentManager object should be populated with getChildFragmentManager() to work properly. For more info look at my BakingApp project DetailStepWideScreenFragment.java

    GitHub Repos

    Fragment Wrapper:

    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;
        }
    
    }