ViewPager无限循环滑动无卡顿,详解OnPageChangeListener

记得之前写过一篇实现viewPager循环滑动的,但当时也就是只想着使用,没去深究什么原因,这次换种方法实现循环滑动,而且没有任何卡顿跳跃的状况。

参考文章:http://blog.csdn.net/mtt1987/article/details/38797107

http://blog.csdn.net/xipiaoyouzi/article/details/12121131   

大致思路,就是在图片的前后各加一张图片,比较上一篇那种直接将数量置为最大数,实在是好太多了。代码如下:

imgIDs=new int[]{R.drawable.img1,R.drawable.img2,R.drawable.img3,R.drawable.img4};
pageList=new ArrayList<>();
addImgView(imgIDs.length-1);
for(int i=0;i<imgIDs.length;i++){
    addImgView(i);
}
addImgView(0);
毕竟很多代码都在 上一篇博客写过了,这一篇也就只贴些关键性的代码。


配置好数据源之后,关键是滑动之后的操作,如果滑动到了最后一张照片,我们立刻setCurrentItem到第1张照片,如果滑动到了第0张照片,那么就setCurrentItem到倒数第二张照片。代码如下:

    mviewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            Log.e("-----","------->>>onPageScrolled>>>position="+position+">>>positionOffset="
                    +positionOffset+">>>positionOffsetPixels="+positionOffsetPixels);
        }

        @Override
        public void onPageSelected(int position) {
            mIsChanged=true;
            if(position==0){
                currentIndex=pageList.size()-2;
            }else if(position==pageList.size()-1){
                currentIndex=1;
            }else{
                currentIndex=position;
            }

            Log.e("----","------------------>>>OnPageSelected");
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            if(state==ViewPager.SCROLL_STATE_IDLE){
                if(mIsChanged){
                    mIsChanged=false;
                    mviewPager.setCurrentItem(currentIndex,false);
                }
            }

            if(state==ViewPager.SCROLL_STATE_DRAGGING){
                Log.e("-----ScrollState------","-----SCROLL_STATE_DRAGGING-----");
            }else if(state==ViewPager.SCROLL_STATE_SETTLING){
                Log.e("-----ScrollState------","-----SCROLL_STATE_SETTLING-----");
            }else if(state==ViewPager.SCROLL_STATE_IDLE){
                Log.e("-----ScrollState------","-----SCROLL_STATE_IDLE-----");
            }
        }
    });
上面的思路,关键性的代码也都在onPageSelected()方法中,很容易看懂。可是我们居然没在里面发现setCurrentItem,这是因为我把它放到了onPageScrollStateChanged()方法中,这也是我们无限循环滑动不卡顿,不跳跃的关键。代码中的Log也都是为了下面的讲解。


接下里我们的Log就要起作用了,说下OnPageChangeListener这个接口的三个方法:

onPageScrolled(int position, float positionOffset, int positionOffsetPixels),当页面正在滑动的时候调用此方法,一直到页面在停止之前,都会得到调用。其中,postion代表当前页面;positionOffset值在0到1之间,指当前页面偏移的百分比;positionOffsetPixels代表当前页面偏移的像素位置。

onPageSelected(int position),当一个新页面将要被确定下来的时候调用这个方法。其中postion代表新页面的index。

onPageScrollStateChanged(int state),在滑动状态发生改变之后会被调用。其中state有三种状态,SCROLL_STATE_DRAGGING是指当前页面正在被用户拖动;SCROLL_STATE_SETTLING则指用户的滑动动作已经结束,可以确认新页面了;SCROLL_STATE_IDLE则指当前页面处于空闲稳定的状态。

光这样说是没用的,我随意滑动一个页面,我们直接看打印的log吧,那样会更加清楚的。


这样应该很清楚了,从最开始我们滑动页面,进入的状态是SCROLL_STATE_DRAGGING,之后根据我们滑动的速度,滑动的位置,可以判断我们确实是想滑动到下一个页面。这时就变成了SCROLL_STATE_SETTLING,可以确定新页面的index了,也就执行了onPageSelected()的方法。其中onPageScrolled()的偏移位置也一直提示着我们在不断的滑向下一个页面。之后页面确定下来,状态也就变为了SCROLL_STATE_IDLE。

这也就是我们为什么要在SCROLL_STATE_IDLE这个时候才去执行setCurrentItem这个方法的原因。如果直接在onPageSelected()方法中执行setCurrentItem,那个时候整个滑动动作都未结束,当然会有卡顿或者跳跃的感觉。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值