Android 如何从FragmentPagerAdapter返回多个片段

Android 如何从FragmentPagerAdapter返回多个片段,android,android-fragments,android-tablayout,fragmentpageradapter,Android,Android Fragments,Android Tablayout,Fragmentpageradapter,如果将TabLayout与FragmentPagerAdapter一起使用,则重写的函数getItem(int位置)只返回一个片段。在大屏幕的情况下,我想有2个碎片要返回。 我怎么做?应该将这两个片段包装成一个片段并使用它,还是有更好的解决方案 FragmentPagerAdapter: public class SectionsPagerAdapter extends FragmentPagerAdapter { public SectionsPagerAdapter(Fragmen

如果将
TabLayout
FragmentPagerAdapter
一起使用,则重写的函数getItem(int位置)只返回一个片段。在大屏幕的情况下,我想有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!");
        }
    }
    @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));
    }
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();
    }
}
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;
    }

}
然后在我的活动onCreate:

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

}

我看你这里没有多少回旋余地

这两个选项是唯一的:

  • 返回一个片段和两个嵌套片段(包装片段)
  • 您将返回两个片段,每个片段都锚定到自己的选项卡上 若您希望两个片段出现在ViewPager的单一页面上,那个么您别无选择,只能将它们包装起来。
    否则,滑动将在这两个片段之间进行,这与它们完全不同的情况相同,即不相关。

    好的,我成功地解决了这个问题,使用了一个
    片段
    作为子片段,由另外两个片段组成。 在这种情况下,不要忘记使用
    getChildFragmentManager()
    填充
    FragmentManager
    对象才能正常工作。 有关更多信息,请查看我的BakingApp项目
    detailStepWideCreenFragment.java

    片段包装器:

    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!");
            }
        }
    
        @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));
        }
    
    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();
        }
    }
    
    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;
        }
    
    }
    
    PagerAdapter:

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

    我认为返回一个包裹其他两个的片段是明智的解决方案