Viewpager图片自动轮播无限循环是Android开发中经常用到的功能,功能实现起来也比较简单。虽然如此,但是很多情况下做出来的效果并不太让人满意,甚至有些上线的项目自动轮播上也会出现一些bug。比如切换过程中出现空白页面,有些甚至在滑动过程中造成程序崩溃。本篇文章将实现ViewPager图片自动轮播无限循环,而且页面切换效果非常流畅。
还是先看效果图:
页面循环切换最容易出现问题的地方就是在最后一页向第一页切换或者第一页向最后一页切换时,在这个切换过程中很容易出现空白页面。怎么解决这个问题?
下面说下本程序的实现的思路。在第一张图片前和最后一张图片后分别添加一个ImageView,最前边的ImageView背景设置为最后一张图片,最后一个ImageView背景设置第一张图片。当我们判断滑动到最后一个ImageView时则设置ViewPager.setCurrentItem(1),让其自动切换到第一张图片,这样在从最后一页切换到第一页时由于图片是用的同一张图片,所以就会使切换效果显得很流畅自然。同理,当滑动到第0个ImageView时用ViewPager.setCurrentItem(length)自动切换到倒数第二张图片,第0个ImageView和倒数第二个ImageView图片相同,这样就使滑动效果显得很自然。
看下代码实现:
下面为初始化控件的方法,其中有一个LinearLayout是包含五个小圆点的布局,在后边的代码中可以通过判断图片的张数,动态的添加小圆点。
private void initView() {
mViewPager= (ViewPager) findViewById(R.id.vp_main);
mLinearLayoutDot= (LinearLayout) findViewById(R.id.ll_main_dot);
}
初始化数据的方法,mImageViewList为存放图片的ImageView的集合,
mImageViewDotList为存放小圆点的ImageView的集合。images是一个整形数组,里边存放了ViewPager的五张图片。下边的for循环是为了动态的创建ImageView,之所以循环images.length+2次是因为我们在前后各加了一个ImageView。
private void initData() {
mImageViewList=new ArrayList<>();
mImageViewDotList=new ArrayList();
ImageView imageView;
for(int i=0;i<images.length+2;i++){
if(i==0){
imageView=new ImageView(this);
imageView.setBackgroundResource(images[images.length-1]);
mImageViewList.add(imageView);
}else if(i==images.length+1){
imageView=new ImageView(this);
imageView.setBackgroundResource(images[0]);
mImageViewList.add(imageView);
}else{
imageView=new ImageView(this);
imageView.setBackgroundResource(images[i-1]);
mImageViewList.add(imageView);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
动态的添加小圆点,共有images.length个页面,因此应该添加images.length个小圆点
private void setDot() {
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(15,15);
params.rightMargin=20;
for(int i=0;i<images.length;i++){
ImageView imageViewDot=new ImageView(this);
imageViewDot.setLayoutParams(params);
imageViewDot.setBackgroundResource(R.drawable.red_dot_night);
mLinearLayoutDot.addView(imageViewDot);
mImageViewDotList.add(imageViewDot);
}
mImageViewDotList.get(dotPosition).setBackgroundResource(R.drawable.red_dot);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
设置ViewPager,并为ViewPager设置页面切换的监听事件。
private void setViewPager() {
MyPagerAdapter adapter=new MyPagerAdapter(mImageViewList);
mViewPager.setAdapter(adapter);
mViewPager.setCurrentItem(currentPosition);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if(position==0){
currentPosition=images.length;
dotPosition=images.length-1;
}else if(position==images.length+1){
currentPosition=1;
dotPosition=0;
}else{
currentPosition=position;
dotPosition=position-1;
}
mImageViewDotList.get(prePosition).setBackgroundResource(R.drawable.red_dot_night);
mImageViewDotList.get(dotPosition).setBackgroundResource(R.drawable.red_dot);
prePosition=dotPosition;
}
@Override
public void onPageScrollStateChanged(int state) {
if(state==ViewPager.SCROLL_STATE_IDLE){
mViewPager.setCurrentItem(currentPosition,false);
}
}
});
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
用Handler控制页面每隔3秒自动切换
private void autoPlay() {
new Thread(){
@Override
public void run() {
super.run();
while(true){
SystemClock.sleep(3000);
currentPosition++;
handler.sendEmptyMessage(1);
}
}
}.start();
}
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==1){
mViewPager.setCurrentItem(currentPosition,false);
}
}
};