关闭

ViewPager的视差背景效果

304人阅读 评论(0) 收藏 举报
分类:

这很的app中都用到了ViewPager滑动背景也跟着变动,最近写了个解锁项目其中也需要实现这个效果自己也写了下,由于锁屏只有2个页面,所有ViewPager只2个页面的滑动,如果想要多个页面可以修改下代码就行了,代码有注释,修改也比较容易.代码如下:

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

@SuppressLint("NewApi")
public class ParallaxViewPager extends ViewPager {

	public static final int FIT_WIDTH = 0;
	public static final int FIT_HEIGHT = 1;
	public static final float OVERLAP_FULL = 1f;
	public static final float OVERLAP_HALF = 0.5f;
	public static final float OVERLAP_QUARTER = 0.25f;
	public Bitmap bitmap;
	private Rect source, destination;
	private int scaleType;
	private Paint paint;
	private OnPageChangeListener secondOnPageChangeListener;

	public ParallaxViewPager(Context context) {
		super(context);
		init();
	}

	public ParallaxViewPager(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	private void init() {
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		source = new Rect();
		destination = new Rect();
		scaleType = FIT_HEIGHT;
		//滑动时会调用这个方法 所以我们就在这个方法了来处理图片的移动
		setOnPageChangeListener(new OnPageChangeListener() {
			@Override
			//position 是ViewPager展示的是第几个位置 positionOffset移动时变化的值(如从第0页移动到1页,它的变化0~1之间变化)
			public void onPageScrolled(int position, float positionOffset,
					int positionOffsetPixels) {
				if (bitmap != null) {
					if (position == 0) {
						//这是从0页滑动第1页
						//source 和destination是图片矩阵,由于后面的背景只有一张source矩阵的移动范围只有getWidth/8,
						//如果太大了ViewPagery移动到第二页的时候背景就感觉不到移动了,
						//而ViewPager有两页,所以destination矩阵的移动范围是两个getWidth那么宽
						source.left = (int) ((getWidth() / 8) * positionOffset);
						source.right = getWidth() + source.left;
						destination.left = (int) ((getWidth() * positionOffset) - getWidth());
						destination.right = (int) (0 + (getWidth() * positionOffset));

					} else {
						//这是从1页滑动第0页移动的范围刚好相反
						source.left = (int) ((getWidth() / 8) - (getWidth() / 8)
								* positionOffset);
						source.right = getWidth() + source.left;
						destination.left = (int) ((0 - getWidth()
								* positionOffset));
						destination.right = (int) (getWidth() - (getWidth() * positionOffset));
					}

					postInvalidate();
				}

				if (secondOnPageChangeListener != null) {
					secondOnPageChangeListener.onPageScrolled(position,
							positionOffset, positionOffsetPixels);
				}
			}

			@Override
			public void onPageSelected(int position) {
				if (secondOnPageChangeListener != null) {
					secondOnPageChangeListener.onPageSelected(position);
				}
			}

			@Override
			public void onPageScrollStateChanged(int state) {
				if (secondOnPageChangeListener != null) {
					secondOnPageChangeListener.onPageScrollStateChanged(state);
				}
			}
		});
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		destination.top = 0;
		destination.bottom = h;
		if (getAdapter() != null && bitmap != null)
			calculateParallaxParameters();
	}

	private void calculateParallaxParameters() {
		if (bitmap.getWidth() < getWidth()
				&& bitmap.getWidth() < bitmap.getHeight()
				&& scaleType == FIT_HEIGHT) {
			Log.w(ParallaxViewPager.class.getName(),
					"Invalid bitmap bounds for the current device, parallax effect will not work.");
		}
		source.top = 0;
		source.bottom = bitmap.getHeight();

	}

	/**
	 * Sets the background from a resource file.
	 * 
	 * @param resid
	 */
	@Override
	public void setBackgroundResource(int resid) {
		bitmap = BitmapFactory.decodeResource(getResources(), resid);
	}

	/**
	 * Sets the background from a Drawable.
	 * 
	 * @param background
	 */
	@Override
	public void setBackground(Drawable background) {
		bitmap = ((BitmapDrawable) background).getBitmap();
	}

	/**
	 * Deprecated. Sets the background from a Drawable.
	 * 
	 * @param background
	 */
	@Override
	public void setBackgroundDrawable(Drawable background) {
		bitmap = ((BitmapDrawable) background).getBitmap();
	}

	/**
	 * Sets the background from a bitmap.
	 * 
	 * @param bitmap
	 * @return The ParallaxViewPager object itself.
	 */
	public ParallaxViewPager setBackground(Bitmap bitmap) {
		this.bitmap = bitmap;
		return this;
	}

	//设置图片展示的属性
	public ParallaxViewPager setScaleType(final int scaleType) {
		if (scaleType != FIT_WIDTH && scaleType != FIT_HEIGHT)
			throw new IllegalArgumentException(
					"Illegal argument: scaleType must be FIT_WIDTH or FIT_HEIGHT");
		this.scaleType = scaleType;
		return this;
	}

	/**
	 * Sets the amount of overlapping with the setOverlapPercentage(final float
	 * percentage) method. This is a number between 0 and 1, the smaller it is,
	 * the slower is the background scrolling.
	 * 
	 * @param percentage
	 * @return The ParallaxViewPager object itself.
	 */
	public ParallaxViewPager setOverlapPercentage(final float percentage) {
		if (percentage <= 0 || percentage >= 1)
			throw new IllegalArgumentException(
					"Illegal argument: percentage must be between 0 and 1");
		return this;
	}

	/**
	 * Recalculates the parameters of the parallax effect, useful after changes
	 * in runtime.
	 * 
	 * @return The ParallaxViewPager object itself.
	 */
	public ParallaxViewPager invalidateParallaxParameters() {
		calculateParallaxParameters();
		return this;
	}
	//画背景
	@Override
	protected void onDraw(Canvas canvas) {
		if (bitmap != null) {
			canvas.drawBitmap(bitmap, source, destination, paint);
		}
	}
	//viewPager滑动的监听
	public void addOnPageChangeListener(OnPageChangeListener listener) {
		secondOnPageChangeListener = listener;
	}
}

具体的调用如下:

//初始化
viewPager = (ParallaxViewPager)findViewById(R.id.lock_viewpager);
//设置背景
viewPager.setBackgroundDrawable(new BitmapDrawable());
//ViewPager设置适配器		
viewPager.setAdapter(new MyViewPagerAdapter());
//设置滑动监听
viewPager.addOnPageChangeListener(this);
//跳转到指定的页面
viewPager.setCurrentItem(mList.size());


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:24196次
    • 积分:799
    • 等级:
    • 排名:千里之外
    • 原创:58篇
    • 转载:4篇
    • 译文:0篇
    • 评论:3条
    文章分类
    最新评论