ViewPager - 在片段页面中创建一个新片段

时间:2017-04-08 05:19:04

标签: android android-layout android-fragments android-viewpager material-design

我有ViewPager个活动。 ViewPager还有一个TabLayout,其中包含3个标签:FragmentAFragmentBFragmentC,每个标签对应于要显示的3个页面之一ViewPager。在FragmentB的内部虽然我会有一个按钮。我现在需要能够单击此按钮并创建一个新的片段FragmentD,它将超过FragmentB。这个新片段需要有一个带有后退箭头的操作栏,以便它可以返回FragmentB。在所有这些选项卡中,选项卡仍应显示FragmentB是活动选项卡。我已经研究过嵌套的片段,但是我无法使它工作。我也尝试从我的片段创建对viewpager acitivty的引用,并使用我的新片段的位置调用getItem方法,但这不起作用。这是我现在的代码。它是一个创建ViewPager的活动。创建了ViewPager 3个片段的内部,并且还创建了TabLayout

public class MyActivity extends AppCompatActivity {

    ViewPager viewPager;
    PagerAdapter pagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        // Get the ViewPager and set it's PagerAdapter so that it can display items
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        pagerAdapter = new PagerAdapter(getSupportFragmentManager(), MyActivity.this);
        viewPager.setAdapter(pagerAdapter);

        viewPager.setOffscreenPageLimit(3);

        // Give the TabLayout the ViewPager
        TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.setupWithViewPager(viewPager);

        // Iterate over all tabs and set the custom view
        for (int i = 0; i < tabLayout.getTabCount(); i++) {
            TabLayout.Tab tab = tabLayout.getTabAt(i);
            tab.setCustomView(pagerAdapter.getTabView(i));
        }
    }

    class PagerAdapter extends FragmentPagerAdapter {

        String tabTitles[] = new String[] { "FragmentA", "FragmentB", "FragmentC", };
        public Fragment[] fragments = new Fragment[tabTitles.length];
        Context context;

        public PagerAdapter(FragmentManager fm, Context context) {
            super(fm);
            this.context = context;
        }

        @Override
        public int getCount() {
            return tabTitles.length;
        }

        @Override
        public Fragment getItem(int position) {

            switch (position) {
                case 0:
                    return new MyFragmentA();
                case 1:
                    return new MyFragmentB(); //Inside of fragment B I will have a button. If that button is clicked this fragment needs to be replaced with a new fragment temporarliy, FRAGMENTD, which will have an anctionbar to be able to go back to fragment B. The tabs should show that the user is technically still in FragmentB tab. 
                case 2:
                    return new MyFragmentC();
            }

            return null;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            // Generate title based on item position
            return tabTitles[position];
        }

        public View getTabView(int position) {
            View tab = LayoutInflater.from(MyActivity.this).inflate(R.layout.custom_tab, null);
            TextView tv = (TextView) tab.findViewById(R.id.custom_text);
            tv.setText(tabTitles[position]);
            return tab;
        }

        //This populates your Fragment reference array:
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
            fragments[position]  = createdFragment;
            return createdFragment;
        }
    }


}

1 个答案:

答案 0 :(得分:0)

我认为有这个目的吗?

public Fragment[] fragments = new Fragment[tabTitles.length];

您只需指定它,但绝不使用其元素。

您可以像这样使用它来懒洋洋地创建片段

@Override
public Fragment getItem(int position) {
    Fragment f = fragments[position];

    if (f == null) {
        switch (position) {
            case 0:
                f = new MyFragmentA();
                break;
            case 1:
                f = new MyFragmentB();
                break;
            case 2:
                f = new MyFragmentC();
                break;
        }
        fragments[position] = f;
    }

    return f;
}

或者看这里,这没有正确实现,因为super.instantiateItem(container, position)永远不会创建你想要的三个Fragment类中的任何一个。

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
        fragments[position]  = createdFragment;
        return createdFragment;
    }

所以,我会删除这个方法

  

FragmentB里面虽然我有一个按钮。我现在需要能够单击此按钮并创建一个新的片段FragmentD,它将超过FragmentB ......在所有这些选项卡中,选项卡仍应显示FragmentB是活动选项卡。

您需要从FragmentB回调到活动

How to implement OnFragmentInteractionListener

然后,在Activity回调中,您创建并且可能&#34;替换第2页&#34; ViewPager的。{

  

这个新片段需要有一个带有后退箭头的操作栏,以便它可以返回到FragmentB。

您还需要在该界面中使用第二种方法来onBackPressedFragmentB重新创建并加载FragmentD ViewPager