ViewPager在开发中的使用频率非常的高,此做个总结,本文包括以下几方面:
ViewPager的简介和作用
ViewPager的适配器
ViewPager实现小圆点指示器效果
ViewPager禁止滑动和取消滑动效果
ViewPager滑动到最后一条再次滑动的监听
1.ViewPager的简介和作用
ViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的view
1)ViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的view类。
2)ViewPager类需要一个PagerAdapter适配器类给它提供数据。
3)ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用。
2.ViewPager的适配器
实现一个最基本的PagerAdapter
public class AdapterViewpager extends PagerAdapter {
private List<View> mViewList;
public AdapterViewpager(List<View> mViewList) {
this.mViewList = mViewList;
}
@Override
public int getCount() {//必须实现
return mViewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {//必须实现
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {//必须实现,实例化
container.addView(mViewList.get(position));
return mViewList.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {//必须实现,销毁
container.removeView(mViewList.get(position));
}
}
实现一个最基本的FragmentPagerAdapter
public class AdapterFragment extends FragmentPagerAdapter {
private List<Fragment> mFragments;
public AdapterFragment(FragmentManager fm, List<Fragment> mFragments) {
super(fm);
this.mFragments = mFragments;
}
@Override
public Fragment getItem(int position) {//必须实现
return mFragments.get(position);
}
@Override
public int getCount() {//必须实现
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {//选择性实现
return mFragments.get(position).getClass().getSimpleName();
}
}
FragmentStatePagerAdapter的实现和FragmentPagerAdapter区别在于前者适用于页面更多的界面,从源码中我们可以看出FragmentStatePagerAdapter中fragment实例在destroyItem的时候被真正释放,所以FragmentStatePagerAdapter省内存。FragmentPagerAdapter中的fragment实例在destroyItem的时候并没有真正释放fragment对象只是detach,所以FragmentPagerAdapter消耗更多的内存,带来的好处就是效率更高一些。所以得出这样的结论:FragmentPagerAdapter适用于页面比较少的情况
3实现小圆点指示器方法
Viewpager结合ImageView集成轮播图的功能非常普遍,很多需求还需要指示圆点,由于图片的个数是动态的,这里采用代码动态设置的方法
使用
LinearLayout作为一个父容器
mLlDot = (LinearLayout) view.findViewById(R.id.ll_dot);//指示器容器
根据pagercount数量动态添加圆点和监听
private void
setOvalLayout() {
mLlDot.removeAllViews();//防止重复添加异常
for (int i = 0; i < pageCount; i++) {
mLlDot.addView(inflater.inflate(R.layout.dot, null));//指示器的样式我们可以自己随便定义
}
// 默认显示第一页
mLlDot.getChildAt(0).findViewById(R.id.v_dot)
.setBackgroundResource(R.drawable.dot_selected);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageSelected(int position) {
// 取消圆点选中
mLlDot.getChildAt(curIndex)
.findViewById(R.id.v_dot)
.setBackgroundResource(R.drawable.dot_normal);
// 圆点选中
mLlDot.getChildAt(position)
.findViewById(R.id.v_dot)
.setBackgroundResource(R.drawable.dot_selected);
curIndex = position;//取消上一个,选中下一个坐标点
}
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
});
}
4viewpager禁止滑动,点击按钮滑动取消滑动效果
当我们我们需要通过底部导航按钮切换viewpager并取消滑动动画时可以自定义viewpager重写
public class LyViewPager extends ViewPager{
private boolean scroll = false;
public LyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public LyViewPager(Context context) {
super(context);
}
public boolean isScroll() {
return scroll;
}
public void setScroll(boolean scroll) {//通过开关控制是否可以滑动
this.scroll = scroll;
}
@Override
public void scrollTo(int x, int y) {
super.scrollTo(x, y);
}
@Override
public boolean onTouchEvent(MotionEvent arg0) {
//如果滑动不做处理不滑动返回false,不消费给父控件去处理
if (scroll)
return super.onTouchEvent(arg0);
else {
return false;
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
if (scroll)
return super.onInterceptTouchEvent(arg0);
else {
return false;
}
}
@Override
public void setCurrentItem(int item, boolean smoothScroll) {
super.setCurrentItem(item, smoothScroll);
}
@Override
public void setCurrentItem(int item) {
super.setCurrentItem(item);
}
}
点击viewpager没有切换效果的方法
pager.setCurrentItem(pos, false);//第二个参数设置为false
5viewpager当为最后一条滑动时触发监听
有时我们需要滑动到最后一条时(比如广告页),用户再次滑动直接跳转我们想要的页面可以这样做
实现的方法非常多,下面的这种方式是最简单和简洁的
增加pager监听方法,我们在第三个方法中监听page的滑动状态
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageSelected(int position) {
curIndex = position;//取消上一个,选中下一个坐标点
}
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
public void onPageScrollStateChanged(int state) {
switch (state) {
case ViewPager.SCROLL_STATE_DRAGGING://拖曳状态
isScrolled = false;
break;
case ViewPager.SCROLL_STATE_SETTLING://拖曳后自动归为状态
isScrolled = true;
break;
case ViewPager.SCROLL_STATE_IDLE:////被用户滑动后的最终静止状态 并且是最后一页非滑动情况直接走相关的监听跳转
if (mPager.getCurrentItem() == mPager.getAdapter().getCount() - 1 && !isScrolled) {
mGoToDianbaoListener.go(mPager.getAdapter().getCount() - 1);//这里使用了接口回调,可以根据自己的需求监听
}
isScrolled = true;
break;
}
}
});