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;
                }
            }
        });