记得之前写过一篇实现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,那个时候整个滑动动作都未结束,当然会有卡顿或者跳跃的感觉。