在ViewPager的实现功能中不仅可以完成手动的页面滑动,图片滑动等,还有一个很重要的功能就是可以实现图片的自动轮播效果,而相对于微信页面的滑动来说,我们要实现的自动轮播效果的底部小图标不再在布局文件中把它写死,而是动态的把加入到所要显示的部位。


ViewPager的基本用法之前说过,首先通过findViewById找到布局中的ViewPager,声明一个放图片的数组,然后利用for循环把图片都遍历进去


```

private void initView() { 

// TODO Auto-generated method stub 

for (int i = 0; i < imgs.length; i++) { 

View v = View.inflate(this, R.layout.viewitem, null); 

ImageView img=(ImageView)v.findViewById(R.id.img); 

img.setImageResource(imgs[i]); 

imgList.add(img); 

} 

MyAdapter adapter=new MyAdapter(imgList); 

vp.setAdapter(adapter); 

} 

 ```


然后需要添加一个适配器,自己拟定一个MyAdapter的是适配器继承PagerAdapter类,会有4个方法,2个自动给出,2个是手动的添加。



``` 

 public class MyAdapter extends PagerAdapter{ 

private List<ImageView> imgList=new ArrayList<ImageView>(); 

public MyAdapter(List<ImageView> imgList){ 

this.imgList=imgList; 

}


@Override

iOS collectionview轮播 viewpager实现轮播_ide


public int getCount() { 

// TODO Auto-generated method stub 

return Integer.MAX_VALUE; 

} 



@Override 

public boolean isViewFromObject(View arg0, Object arg1) { 

// TODO Auto-generated method stub 

return arg0==arg1; 

} 

 

@Override 

public Object instantiateItem(ViewGroup container, int position) { 

// TODO Auto-generated method stub 

int p=position%imgList.size(); 

ImageView img=imgList.get(p); 

ViewParent parent=img.getParent(); 

if(parent!=null){ 

ViewGroup vg=(ViewGroup) parent; 

vg.removeView(img); 

} 

container.addView(imgList.get(p)); 

return imgList.get(p); 

} 

@Override 

public void destroyItem(ViewGroup container, int position, Object object) { 

// TODO Auto-generated method stub 

int p=position%imgList.size(); 

container.removeView(imgList.get(p)); 

} 

} 

 ```


1、getCount方法:


返回值是Integer.MAX_VALUE,是因为要让轮播的图片一直循环下去,所以要给一个无限大的数,Integer是整型的包装类,MAX_VALUE是其中无限大的数。


2、isViewFromObject方法:


返回值是让arg0=arg1。


3、instantiateItem方法(手动添加的方法):


定义一个p,让(position%imgList.size()),因为imgList.size是添加图片的张数(n),所以当position%4的时候一直会在0~n之前循环。也就可以实现轮播的效果,但是要注意的一个点是          ※※一个控件(view)只能被加进一个viewgroup里面※※         最后将得到的list中的每个position返回回去。


4、destroyItem方法(手动添加):


这个方法就是把不需要的视图删除掉,销毁。也是根据之前的(position%imgList.size())得循环方式。




然后把这个适配器添加到之前学过的initView的方法中。




把图片的轮播方法写好之后然后要开始添加图片下方轮播的小点的方法----inIT(),在这个方法中不仅要实现小点的轮播效果,而且还要实现手动滑动时的优化显示。




```

private void initBottom() { 

// TODO Auto-generated method stub 

bottomImages = new ImageView[imgList.size()]; 

 

for(int j = 0; j<bottomImages.length; j++){ 

ImageView bottom=new ImageView(this); 

//给bottom控件加上布局属性,参数是控件的宽高 

LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(60, 60); 

//外边距左 上 右 下 

params.setMargins(1, 0, 1, 0); 

bottom.setLayoutParams(params); 

//设置底部小圆点的初始状态 

if(j==0){ 

bottom.setImageResource(R.drawable.d1); 

}else{ 

bottom.setImageResource(R.drawable.d2); 

} 

bottomImages[j]=bottom; 

//把小圆点的视图加到线性布局里 

indicator.addView(bottom); 

} 

vp.setOnPageChangeListener(new OnPageChangeListener() { 

 

@Override 

public void onPageSelected(int arg0) { 

// TODO Auto-generated method stub 

//将当前显示页面的position对应的小圆点设置为选中状态 

for(int i=0; i<bottomImages.length;i++){ 

int p=arg0%imgList.size(); 

if(i==p){ 

bottomImages[i].setImageResource(R.drawable.d1); 

}else{ 

bottomImages[i].setImageResource(R.drawable.d2); 

} 

} 

currentIndex=arg0; 

} 

 

@Override 

public void onPageScrolled(int arg0, float arg1, int arg2) { 

// TODO Auto-generated method stub 

 

} 

 

@Override 

public void onPageScrollStateChanged(int arg0) { 

// TODO Auto-generated method stub 

//当手动滑动视图的时候,将isTouch标志位设为true 

if(arg0==ViewPager.SCROLL_STATE_IDLE){ 

isTouch=false; 

}else{ 

isTouch=true; 

} 

} 

}); 

} 

 ```


我们要声明一个的initBottom的ImageView数组(它的长度是之前图片的长度),通过for循环给bottom控件加上布局属性,其中有几个重要的布局方法,在上面的代码中明确标明。


然后设置底部圆点的初始状态,根据下坐标把圆点动态的添加到之前的线性布局中。




接下来是手动滑动的需要改变的状态,在onPageSelected方法中设置当前显示页面的position对应的圆点设置为选中状态。


要在全局设置一个boolean类型的变量 初始值设为false;


//是否手动滑动视图


private boolean isTouch=false;


当手动滑动视图(也就是上面的图片的时候),将isTouch标志位设为true。




在无需手动滑动视图的时候,自动轮播视图是需要每隔几秒图片会切换,我们可能看到淘宝的轮播图片,所以接下需要通过之前所学的Thread方法,让图片每隔3秒自动切换。




```

Thread thread=new Thread(new Runnable() { 

 

@Override 

public void run() { 

// TODO Auto-generated method stub 

while(isAuto){ 

try { 

thread.sleep(3000); 

handler.sendEmptyMessage(0); 

} catch (InterruptedException e) { 

// TODO Auto-generated catch block 

e.printStackTrace(); 

} 

} 

} 

}); 

Handler handler=new Handler(){ 

public void handleMessage(android.os.Message msg) { 

if(msg.what==0){ 

//如果手动滑动时不处理 

if(isTouch){ 

return; 

} 

//如果是自动轮播时,让代表显示页面的指示位置+1; 

currentIndex++; 

vp.setCurrentItem(currentIndex); 

} 

}; 

}; 

 ````


相对于之前的逻辑,这个方法还是比较简单,只是需要注意的是:在全局声明一个


在Thread方法中当判断是否需要自动轮播的时候,如果需要轮播就就让图片停三秒跳转下一张。

//是否自动轮播 

private boolean isAuto=true;


在定义的Handler类中要注意的就是如果是手动滑动的时候让自动轮播的方法不处理。




最后为了让代码的完整性和友好,要添加一个方法让线程停止运行。


``` 

 protected void onDestroy() { 

super.onDestroy(); 

//让线程停止; 

isAuto=false; 

}; 

 ``` 



 ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/3153810-21f7bfd759e97449.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

这段代码能实现的功能片段,一下就会想到淘宝。




这就是一个比较完整的自动轮播效果和手动可滑动的效果。


几个比较重要的点:1、自己写的适配器中 instantiateItem方法要注意循环的方法和一个控件(view)只能被加进一个viewgroup。


2、动态的添加小圆点的时候判断的方法和添加的方法,还有手动打断的滑动效果。


3、代码的完整性,和功能的实现。




-----------------------------------------------------------------------------------------------------------


相互学习,共同进步!


-------------------------------------------------------------------------------------------------------------