如何在碎片中设置ViewPager

56

我需要在一个片段中放置ViewPager,但我有两个片段,第一个是我的菜单,第二个片段我想用作ViewPagerIndicator。

但是一个片段不能包含另一个片段...那我需要怎么做?

输入图像描述

6个回答

106

从Android 4.2开始,支持嵌套片段。http://developer.android.com/about/versions/android-4.2.html#NestedFragments支持库现在也包括了旧版Android版本的支持。

因此,您可以像这样做:

@Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    ViewPager mViewPager = (ViewPager) view.findViewById(R.id.viewPager);
    mViewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
    }

完整实现在此处可用:https://github.com/marcoRS/nested-fragments/tree/master/src/com/burnside/digital/nestedfragments


1
但这是不可能的,因为我不能将FragmentActivity放在我的Fragment 2中,因为fragment的父级是FragmentActivity,而子级(fragment 2)需要成为一个fragmentActivity才能拥有选项卡。在github示例中也没有将一个fragment放入另一个fragment中。 - Gilberto Ibarra
你为什么需要拥有片段1?难道你不能只拥有一个引用不同片段的ViewPager,然后在其下方放置片段2吗? - Ryan S
但是代码片段 1 始终相同,这样就会显得有所变化,而我不想要这样。你有什么想法吗? - Gilberto Ibarra
1
使用getChildFragmentManager()而不是getFragmentManager()或getSupportFragmentManager()来初始化适配器,这样肯定会起作用的 :) ,编码愉快。 - Ramkesh Yadav
成功了。在片段内初始化ViewPagerAdapter时,我使用了getSupportFragmentManager()而不是getChildFragmentManager()。 - Kunwar Shekhar Singh
显示剩余2条评论

38

如果你想在Fragment内部获取FragmentManager,你必须使用getChildFragmentManager(),而不是使用getSupportFragmentManager()。 但是,你不应该使用FragmentStatePagerAdapter,而应该使用FragmentPagerAdapter


3
"不要使用FragmentStatePagerAdapter而使用FragmentPagerAdapter",三重否定的意思是我们应该使用FragmentPagerAdapter,对吗?为什么呢?需要注意的是,这里只涉及翻译,不包括解释或其他内容。 - Aditya Anand
但是你不应该使用FragmentStatePagerAdapter而不是FragmentPagerAdapter。再一次,FragmentPagerAdapter拯救了我的一天。这已经发生了两次,但我直到看到这个才意识到。原因是:如果您尝试在一个片段中的ViewPager中使用FragmentStatePagerAdapter,如果您导航到另一页并返回,则您的选项菜单可能会混乱(或根本不显示)。 - eddym

18

在Fragments内,只需使用getChildFragmentManager()代替getSupportFragmentManager()

在Fragments内部

new ViewPagerAdapter(getChildFragmentManager());

活动内部

new ViewPagerAdapter(getSupportFragmentManager());

简单的代码

fragment_sample.xml 布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tablayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

SampleFragment.java

public class SampleFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View fragmentView = inflater.inflate(R.layout.fragment_sample, container, false);
        return fragmentView;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // find views by id
        ViewPager viewPager = view.findViewById(R.id.viewpager);
        TabLayout tabLayout = view.findViewById(R.id.tablayout);

        // attach tablayout with viewpager
        tabLayout.setupWithViewPager(viewPager);

        ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());

        // add your fragments
        adapter.addFrag(new SampleFragment(), "Tab1");
        adapter.addFrag(new SampleFragment2(), "Tab2");
        adapter.addFrag(new SampleFragment3(), "Tab3");

        // set adapter on viewpager
        viewPager.setAdapter(adapter);
    }
}

ViewPagerAdapter.java

// common adapter for all view pager in your project.
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }

    public void addFrag(Fragment fragment) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add("");
    }

    public void addFrag(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }
}

重要相关链接


在这行代码adapter.addFrag(new SampleFragment(), "Tab1");中,SampleFragment()应该被改为SampleFragment1(),因为SampleFragment()已经被定义为持有ViewPager的片段。@Khemraj - Hadas Kaminsky

4

这是可能的。尝试在view_pager_fragment.xml文件中编写以下代码:

<android.support.design.widget.AppBarLayout
    android:id="@+id/appBarLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.design.widget.TabLayout
        android:id="@+id/tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

ViewPagerFragment

ViewPager viewPager;
TabLayout tabLayout;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.tracks, container, false);

    viewPager = (ViewPager) view.findViewById(R.id.viewpager);
    tabLayout = (TabLayout) view.findViewById(R.id.tab);

    return view;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    setupViewPager(viewPager);
    tabLayout.setupWithViewPager(viewPager);

    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
}

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getChildFragmentManager());``

  

    viewPager.setAdapter(viewPagerAdapter);
}

private class ViewPagerAdapter extends FragmentPagerAdapter {

    public ViewPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @Override
    public Fragment getItem(int position) {
        if(position == 0) return new FirstFragment();
        if(position == 1) return new SecoundFragment();
        if(position == 2) return new LoginFragment();
        throw new IllegalStateException("Position is unexpectedly " + position);
    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        if(position == 0) return "First";
        if(position == 1) return "Secound";
        if(position == 2) return "Login";
        throw new IllegalStateException("Position is unexpectedly " + position);
    }
}

0
阅读了一些示例后,您会发现无法在FragmentActivity中嵌套另一个FragmentActivity。不必要使用两个片段,只需要使用FragmentPageAdapter即可...我只需要这样做。
<android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="1" >
</android.support.v4.view.ViewPager>

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:gravity="center"
        android:measureWithLargestChild="true"
        android:orientation="horizontal" >

<Button
            android:id="@+id/first"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="First" >
        </Button>

<Button
            android:id="@+id/last"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Last" >
</Button>
</LinearLayout>

Source: http://www.truiton.com/2013/05/android-fragmentpageradapter-example/


0
使用Android Support V4库,您可以在另一个片段中添加一个片段。尝试使用它,它可能会解决您的问题。

1
但是这是不可能的,因为我不能将FragmentActivity放置在我的Fragment 2中,因为Fragment的父级是一个FragmentActivity,而子级(Fragment 2)需要成为FragmentActivity才能拥有选项卡.. 有什么想法吗? - Gilberto Ibarra
哦,但是等等,你知道吗?你可以把两个片段放到一个没有FragmentActivity的片段中。或者也许你有你自己的理由这么做... - Kyu_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接