Android基础总结——ViewPager

ViewPager控件允许我们构建可以横向滑动的视图,往往配合Fragment一起使用,左右滑动加载不同的fragment实例,进而显示不同的内容。ViewPager使用方法如下:

1. 在Activity布局中使用ViewPager控件




    

2. 在对应的Activity中获取ViewPager实例,并设置PagerAdapter。

ViewPager在某种程度上和RecyclerView类似,RecyclerView需要借助Adapter提供视图,ViewPager则需要PagerAdapter根据数据源获取每一页展示的fragment实例,其中自然也需要用到FragmentManager实例来对fragment进行管理。

google提供了两个ViewPager的子类来帮助我们简化这一过程,分别是FragmentPagerAdapter和FragmentStatePagerAdapter。这两个类使用方法上基本一致,区别在于卸载不再需要的fragment时,各自采用的处理方法不同:

FragmentStatePagerAdapter:会直接销毁不需要的fragment(名字中state的含义表示可以通过onSavedInstanceState(Bundle)方法来保存fragment中的信息,以便在用户切换回来时,通过该信息恢复原来fragment销毁前的状态)。

FragmentPagerAdapter:对于不再需要的fragment,会调用detach(fragment)而非remove(fragment)。这两种方法的区别在于前者只是让fragment在视图上不可见,但是实例依旧保存在内存中,可以随时恢复变为可见状态。后者则是直接销毁内存实例。所以采用这种PagerAdapter,将把ViewPager中所有显示过的fragment保存在内存中。

在开发过程中,具体使用哪一种要根据实际的使用场景决定,如果ViewPager加载的fragment中需要显示占用较多内存的图片,我们应该使用FragmentStatePagerAdapter。如果ViewPager只是用在只有固定几页的标签页上,我们完全不用担心内存占用过的情况下,可以使用FragmentPagerAdapter。

下面看看如何使用,在对应的显示ViewPager的Activity中:

private ViewPager mViewPager;
private List mDataSource;

@Override
protected void onCreate(Bundle savedInstanceState) { 
    mViewPager = findViewById(R.id.activity_view_pager);
    FragmentManager fragmentManager = getSupportFragmentManager();
    mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
        @NonNull
        @Override
        public Fragment getItem(int position) {  // 根据数据源返回对应pager的fragment实例
            DataBean data = mDataSource.get(position);
            return TestFragment.newInstance(data.getId());  // 返回fragment实例
        }

        @Override
        public int getCount() {  // 返回数据源的长度,告知pager的总页数
            return mCrimes.size();
        }
    });
}

setAdapter时需要传入一个抽象类FragmentStatePagerAdapter的子类实例,这里采用匿名内部类的方式,而且传入的参数应当调用的是带有两个参数的构造方法,因为仅传入fragmentManager的构造方法已经废弃了,FragmentStatePagerAdapter.java中:

public abstract class FragmentStatePagerAdapter extends PagerAdapter {    
    ......
    
    @Deprecated
    public FragmentStatePagerAdapter(@NonNull FragmentManager fm) {
        this(fm, BEHAVIOR_SET_USER_VISIBLE_HINT);
    }

    /**
     * Constructor for {@link FragmentStatePagerAdapter}.
     *
     * If {@link #BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT} is passed in, then only the current
     * Fragment is in the {@link Lifecycle.State#RESUMED} state, while all other fragments are
     * capped at {@link Lifecycle.State#STARTED}. If {@link #BEHAVIOR_SET_USER_VISIBLE_HINT} is
     * passed, all fragments are in the {@link Lifecycle.State#RESUMED} state and there will be
     * callbacks to {@link Fragment#setUserVisibleHint(boolean)}.
     *
     * @param fm fragment manager that will interact with this adapter
     * @param behavior determines if only current fragments are in a resumed state
     */
    public FragmentStatePagerAdapter(@NonNull FragmentManager fm,
            @Behavior int behavior) {
        mFragmentManager = fm;
        mBehavior = behavior;
    }

    ......
}

以上就是ViewPager的简单用法。如果我们想要指定进入Activity时显示某个特定的pager,可以通过:

mViewPager.setCurrentItem(i);

指定显示pager的索引来完成。

备注:ViewPager包含的fragment布局中是不支持外边距属性的(会失效)。android:layout_margin将不起作用,我们可以改成android:padding的形式。

你可能感兴趣的:(Android基础总结——ViewPager)