- 参考
ViewPager
Creating Swipe Views with Tabs
Using ViewPager for Screen Slides
ViewPager使用详解(一):PagerAdapter
一. 简介
- 官方介绍
Layout manager that allows the user to flip left and right through pages of data. You supply an implementation of a PagerAdapter to generate the pages that the view shows.
ViewPager是一个让用户可以向左或者向右滑动来浏览视图的LayoutManager,通过PagerAdapter来提供用来显示的数据(页面)。
- 用法
- 搭配普通View使用
- 搭配Fragment使用
二. 三种Adapter
-
PagerAdapter
1.1 官方介绍
Base class providing the adapter to populate pages inside of a ViewPager. You will most likely want to use a more specific implementation of this, such as FragmentPagerAdapter
or FragmentStatePagerAdapter.
ViewPager的基础适配器,通常建议使用FragmentPagerAdapter和FragmentStatePagerAdapter.
1.2 使用方法
- 新建Class继承自PagerAdapter,至少实现以下四个方法:
instantiateItem(ViewGroup, int)
destroyItem(ViewGroup, int, Object)
getCount()
isViewFromObject(View, Object)
- 在对应方法里实现想要的逻辑
1.3 Adapter方法介绍
/**
* 获取View的总数
*
* @return View总数
*/
@Override
public int getCount() {
return 0;
}
/**
* 当ViewPager的内容有所变化时,进行调用。
*
* @param container ViewPager本身
*/
@Override
public void startUpdate(ViewGroup container) {
super.startUpdate(container);
}
/**
* 为给定的位置创建相应的View。创建View之后,需要在该方法中自行添加到container中。
*
* @param container ViewPager本身
* @param position 给定的位置
* @return 提交给ViewPager进行保存的实例对象
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
return super.instantiateItem(container, position);
}
/**
* 为给定的位置移除相应的View。
*
* @param container ViewPager本身
* @param position 给定的位置
* @param object 在instantiateItem中提交给ViewPager进行保存的实例对象
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
/**
* ViewPager调用该方法来通知PageAdapter当前ViewPager显示的主要项,提供给用户对主要项进行操作的方法。
*
* @param container ViewPager本身
* @param position 给定的位置
* @param object 在instantiateItem中提交给ViewPager进行保存的实例对象
*/
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
}
/**
* 当ViewPager的内容变化结束时,进行调用。当该方法被调用时,必须确定所有的操作已经结束。
*
* @param container ViewPager本身
*/
@Override
public void finishUpdate(ViewGroup container) {
super.finishUpdate(container);
}
/**
* 确认View与实例对象是否相互对应。ViewPager内部用于获取View对应的ItemInfo。
*
* @param view ViewPager显示的View内容
* @param object 在instantiateItem中提交给ViewPager进行保存的实例对象
* @return 是否相互对应
*/
@Override
public boolean isViewFromObject(View view, Object object) {
return false;
}
/**
* 保存与PagerAdapter关联的任何实例状态。
*
* @return PagerAdapter保存状态
*/
@Override
public Parcelable saveState() {
return super.saveState();
}
/**
* 恢复与PagerAdapter关联的任何实例状态。
*
* @param state PagerAdapter保存状态
* @param loader 用于实例化还原对象的类加载器
*/
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
super.restoreState(state, loader);
}
/**
* 当ViewPager试图确定某个项的位置是否已更改时调用。默认有两个可选项:POSITION_UNCHANGED和POSITION_NONE。
* POSITION_UNCHANGED:给定项的位置未变更
* POSITION_NONE:给定项不再用于PagerAdapter中
* 其他值:可以根据具体的情况进行调整
*
* @param object 在instantiateItem中提交给ViewPager进行保存的实例对象
* @return
*/
@Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
/**
* 新增方法,目前较多用于Design库中的TabLayout与ViewPager进行绑定时,提供显示的标题。
*
* @param position 给定的位置
* @return 显示的标题
*/
@Override
public CharSequence getPageTitle(int position) {
return super.getPageTitle(position);
}
/**
* 获取给定位置的View的显示宽度比例,该比例是相对于ViewPager。
*
* @param position 给定的位置
* @return View显示的宽度比例
*/
@Override
public float getPageWidth(int position) {
return super.getPageWidth(position);
}
1.4 用途:
- 引导页(不搭配TabLayout)
-
FragmentPagerAdapter
2.1 官方介绍
三. 使用步骤
-
普通ViewPager(使用PagerAdapter的ViewPager)
1.1 xml使用布局
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
android:background="@color/colorPrimary"/>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager_simple"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
1.2 新建适配器PagerAdapter
/**
* Created by Administrator on 2017/4/14.
*/
public class SimplePagerAdapter extends PagerAdapter {
private Context mContext;
private List<View> mViewList;
private final String TAG = getClass().getSimpleName();
private String[] pagerTitiles = {"Page1","page2"};
public SimplePagerAdapter(Context context, List<View> viewList) {
mContext = context;
mViewList = viewList;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(mViewList.get(position));
Log.i(TAG, "instantiateItem: ");
return mViewList.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mViewList.get(position));
Log.i(TAG, "destroyItem: ");
}
@Override
public int getCount() {
Log.i(TAG, "getCount: ");
return mViewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
Log.i(TAG, "isViewFromObject: ");
return view == object;
}
@Override
public CharSequence getPageTitle(int position) {
return pagerTitiles[position];
}
}
1.3 实例化ViewPager,设置适配器
mViewPager = (ViewPager) mRootView.findViewById(R.id.viewpager_simple);
View view1 = inflater.inflate(R.layout.layout_simple_pager1,null);
View view2 = inflater.inflate(R.layout.layout_simple_pager2,null);
List<View> viewList = new ArrayList<>();
viewList.add(view1);
viewList.add(view2);
mSimplePagerAdapter = new SimplePagerAdapter(getContext(),viewList);
mViewPager.setAdapter(mSimplePagerAdapter);
1.4 实例化TabLayout,并setWithViewPager
mTabLayout = (TabLayout) mRootView.findViewById(R.id.tab_layout);
mTabLayout.setupWithViewPager(mViewPager);
-
使用FragmentPagerAdapter的ViewPager
2.1 xml
四. 注意
- 因为ViewPager是在support.v4包里面,因此使用前需要向build.gradle添加
compile 'com.android.support:support-v4:25.2.0'
- ViewPager原本自带两个子控件PagerTitleStrip和PagerTabStrip,但是MD出来之后这个就不怎么用了,想要了解可参看PagerTitleStrip和PagerTabStrip
五. TabLayout详解(点击进入)
六. ViewPager和Fragment搭配的时候数据动态刷新的问题
当ViewPager和Fragment搭配使用的时候,当改变fragment数据之后,由于ViewPager机制,若视图没有销毁则数据不会动态刷新,那么此时我们就需要使用FragmentStatePagerAdapter,该Adapter与FragmentPagerAdapter的区别就是该Adapter在某个fragment不需要的时候就会立即销毁其视图(实测要销毁还是要重写getItemPosition方法)。所以,当需要立即更新视图的时候操作如下:
- 使用FragmentStatePagerAdapter
- 重写getItemPosition
@Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
- 刷新数据并notifyDataSetChanged