无限循环的轮播图ViewPager实现

无限循环的ViewPager实现原理

    实现无限循环的轮播图的原理是:在需要显示的图片的集合的首尾各添加一张图片。因此最后的ViewPager集合展示的图片的数量会比实际的图片多两张,这两张是为了方便切换来实现无限循环的效果的。
   首先,说明一下两个集合,imageIds数组存放的是实际要展示的图片的资源id,imageViewList集合存放的是ViewPager要展示的图片集合。在imaggViewList首尾添加一张图片后,imageViewList.size()=imageIds.length+2;
   imageViewList集合首部添加的图片是imageIds中最后一张图片,也就是说imagViewList集合首部的图片和imageViewList倒数第二张图片是一张图片。imageViewList集合尾部添加的图片是imageIds的第一张图片,也就是说imageViewList集合最后一张图片和imageViewList第二张图片是一张图片。
   下面之间看一张图来理解整个过程:
   注:下面的图解是以当前imageIds中有三个元素来进行讲解的。下标为0,1,2.

接下来直接上代码:
package com.example.viewpagerdemo;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

	private ViewPager viewPager;
	private LinearLayout llPointGroup;
	//图片资源
	private final int[] imageIds = { R.drawable.a, R.drawable.b};
	private List<ImageView> imageViewList;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		init();
	}

	private void init() {
		viewPager = (ViewPager) findViewById(R.id.viewpager);
		llPointGroup = (LinearLayout) findViewById(R.id.ll_point);
		
		initImageViewList();
		initPointList();
		
		viewPager.setAdapter(new MyPagerAdapter());
		viewPager.setCurrentItem(1);//默认是第一个图片。也就是viewpager中下标为1的位置。不是为0的位置。
		
		setListener();
		MyHandler mHandler = new MyHandler();
		mHandler.sendEmptyMessageDelayed(88,3 * 1000);
	}

	private class MyHandler extends Handler{
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			viewPager.setCurrentItem(viewPager.getCurrentItem() + 1 , true);
			sendEmptyMessageDelayed(88,3 * 1000);
		}
	}
	
	private void initImageViewList() {
		imageViewList = new ArrayList<ImageView>();
		//集合头部添加一个ImageView。这个ImageView和真实的最后一个图片是一样的。
		ImageView ivFirst = new ImageView(this);
		ivFirst.setImageResource(imageIds[imageIds.length - 1]);
		imageViewList.add(ivFirst);
		for (int i = 0; i < imageIds.length; i++) {
			ImageView imageView = new ImageView(this);
			imageView.setImageResource(imageIds[i]);
			imageViewList.add(imageView);
		}
		//集合尾部添加一个。这个和真实的第一个图片是一样的。
		ImageView ivLast = new ImageView(this);
		ivLast.setImageResource(imageIds[0]);
		imageViewList.add(ivLast);
	}
	
	private void initPointList() {
		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
				LinearLayout.LayoutParams.WRAP_CONTENT, 
				LinearLayout.LayoutParams.WRAP_CONTENT);
		params.leftMargin = 20;
		//初始化原点集合。原点的个数和imageIds的大小是一致的。imageViewList的大小比imageIds多两个。为了实现无限循环
		for (int i = 0; i < imageIds.length; i++) {
			ImageView imageView = new ImageView(this);
			imageView.setImageResource(R.drawable.point_bg);
			llPointGroup.addView(imageView, params);
			
			//默认选中第一个
			if(i == 0){
				imageView.setEnabled(true);
			}else{
				imageView.setEnabled(false);
			}
		}
	}

	private int lastPosiontion = 1;//上一个位置的下标。默认为1.因为viewpager默认会移动下标为1的位置。
	private void setListener() {
		viewPager.setOnPageChangeListener(new OnPageChangeListener() {
			@Override
			public void onPageSelected(int position) {
				//切换指示点
				int realLastPosition = getRealIndexFromDataList(lastPosiontion);
				int realCurPosition = getRealIndexFromDataList(position);
				if(realCurPosition != realLastPosition){
					//当两次切换的真实下标不一样时才切换指示点
					View lastView = llPointGroup.getChildAt(realLastPosition);
					View curView = llPointGroup.getChildAt(realCurPosition);
					if(lastView != null){
						lastView.setEnabled(false);//上一个点不在选择
					}
					if(curView != null){
						curView.setEnabled(true);//当前点选中
					}
					lastPosiontion = position;
				}
			}
			
			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {}
			@Override
			public void onPageScrollStateChanged(int state) {
				if(state == ViewPager.SCROLL_STATE_IDLE){
					//当前显示在Viewpager中的位置
					int curPosiontion = viewPager.getCurrentItem();
					if(curPosiontion == 0){
						//第一张图片是另加的
						//第一个图片和倒数第二个图片是一样的。切换是不带移动的效果。实现左移无限循环
						viewPager.setCurrentItem(imageViewList.size() - 2,false);
					}
					if(curPosiontion == imageViewList.size() - 1){
						//最后一张图片也是多加的
						//最后一个图片和第二个图片是一样的。切换是不带移动的效果。实现右移无限循环
						viewPager.setCurrentItem(1,false);
					}
				}
			}
		});
	}
	
	
	/**
	 * 根据当前index获取实际在数据集合中的位置下标
	 * @param position	在图片集合imageList中的位置
	 * @return 实际在imageIds中的位置
	 */
	private int getRealIndexFromDataList(int position){
		int realPosition = position - 1;
		int count = imageViewList.size();
		if(realPosition < 0){
			realPosition += count;
		}else if(realPosition >= count){
			realPosition -= count;
		}
		return realPosition;
	}
	
	
	/**
	 * 这里实际是三张图。ImageViewList中首尾各添加了一个图片。
	 * 展示的其实是五张图片。只不过首尾的图片和中间的图片是有重复的。
	 * 这样做是为了实现无限循环。
	 */
	private class MyPagerAdapter extends PagerAdapter{

		@Override
		public int getCount() {
			return imageViewList == null ? 0 : imageViewList.size();
		}

		@Override
		public boolean isViewFromObject(View view, Object obj) {
			return view == obj;
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			container.removeView(imageViewList.get(position));
		}

		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			View view = imageViewList.get(position);
			container.addView(view);
			return view;
		}
	}

}
需要直接下载源码的可以点击下边的链接免费下载:
点击下载源码
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值