首页 > 代码库 > ViewPager 循环滑动+伸缩渐变过度动画实现多图片浏览

ViewPager 循环滑动+伸缩渐变过度动画实现多图片浏览

     


效果图如上。



首先先实现循环:


public class MyAdapter extends PagerAdapter {
	/**
	 * 装ImageView数组
	 */
	private ImageView[] mImageViews;

	/**
	 * 图片资源id
	 */
	private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>();
	private int[] imgIdArray;
	private Context context;
	public MyAdapter(Context context,int []id )
	{
		this.context =context;
		this.imgIdArray = id;
		initImageView();
	}
	
	private void initImageView()
	{
		mImageViews = new ImageView[imgIdArray.length];
		for (int i = 0; i < mImageViews.length; i++) {
				ImageView imageView = new ImageView(context);
				imageView.setBackgroundResource(imgIdArray[i]);
				mImageViews[i] = imageView;
			}
	}
	
	@Override
	public int getCount() {
		return Integer.MAX_VALUE;
	}

	public int getItemCount()
	{
		return mImageViews.length;
	}
	
	@Override
	public boolean isViewFromObject(View arg0, Object arg1) {
		return arg0 == arg1;
	}

	@Override
	public void destroyItem(View container, int position, Object object) {
			((ViewPager) container).removeView(mImageViews[position % imgIdArray.length]);
	}

	
	@Override
	public Object instantiateItem(View container, int position) {
			((ViewPager) container).addView(mImageViews[position % imgIdArray.length],
					0);
			setObjectForPosition(mImageViews[position% imgIdArray.length], position);
		return mImageViews[position% imgIdArray.length];
	}

	private void setObjectForPosition(View view, int position)
	{
		mChildrenViews.put(position, view);
	}
	
	public HashMap<Integer, View> getViewMap()
	{
		return mChildrenViews;
	}
}

1.PagerAdapter的处理

为了达到循环效果我们将getCount()方法返回一个最大整型数

public int getCount() {
		return Integer.MAX_VALUE;
	}
由于item的数量达不到getCount()的数量,当instantiateItem的时候我们对position进行处理

mImageViews[position% imgIdArray.length]
这样处理后instantiateItem返回的VIEW总是在mImageViews[0]-mImageViews[imgIdArray.length]之间。


2.ViewPager的处理

若只是对pagerAdapter进行处理还不够,我们会发现往左滑没有问题,但是往右滑确不能滑动,是因为位置为0,不能往右滑动了。

所以我们先将初始位置设置为图片数量的100倍

public void setAdapter(PagerAdapter arg0) {
		// TODO Auto-generated method stub
		super.setAdapter(arg0);
		//为了在初始状态的时候可以向右滑动
		//当前位置设置为100倍资源数量
		setCurrentItem(((MyAdapter)getAdapter()).getItemCount()*100);
	}

这样处理后两边都可以滑动了.

动画:

对切页进行监听

private OnPageChangeListener PageChangeListener = new OnPageChangeListener() {
		
		@Override
		public void onPageSelected(int arg0) {
			if(pageIndicator!=null && pageIndicator.length>1)
				setSelectBackground(arg0%pageIndicator.length);
		}
		
		@Override
		public void onPageScrolled(int arg0, float arg1, int arg2) {
			// TODO Auto-generated method stub	
			float effectOffset = isSmall(arg1) ? 0 : arg1;
			//获取左边的View
			mLeft = findViewFromObject(arg0);
			//获取右边的View
			mRight = findViewFromObject(arg0 + 1);

			// 添加切换动画效果
			animateAlpha(mLeft, mRight, effectOffset);
			animateXY(mLeft, mRight, effectOffset);
		}
		
		@Override
		public void onPageScrollStateChanged(int arg0) {
			// TODO Auto-generated method stub
			
		}
	};

每次切页涉及到的页面有2个,我们考虑将2个VIEW拿出来用属性动画进行处理。

	protected void animateAlpha(View left, View right, float positionOffset) {
		if (left != null) {
			ViewHelper.setAlpha(left, 1-positionOffset);
		}
		if (right != null) {
			ViewHelper.setAlpha(right, positionOffset);
		}
	}
	
	private void animateXY(View left, View right, float positionOffset) {
			if (left != null) {
				ViewHelper.setPivotX(left, left.getMeasuredWidth());
				ViewHelper.setPivotY(left, 0);
				ViewHelper.setScaleX(left, 1-positionOffset);
			}
			if (right != null) {
				ViewHelper.setPivotX(right, 0);
				ViewHelper.setPivotY(right, 0);
				ViewHelper.setScaleX(right, positionOffset);
			}
	}

源码下载

ViewPager 循环滑动+伸缩渐变过度动画实现多图片浏览