ViewPager的视差背景效果

原创 2015年07月09日 14:32:23

这很的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());


ParallaxViewPager:ViewPager的视差背景效果

源码: Java代码   import android.annotation.SuppressLint;  import android.content.Context;  imp...

Android ParallaxViewPager:ViewPager背景视差Parallax移动

Android ParallaxViewPager:ViewPager背景视察移动 附录的相关文章,实现了一种是当ViewPager左右滑动时候,背景伴随左右滑动,而本文要介绍的Android Par...

利用PageTransformer实现viewpager的视差效果变换和反转特效

利用给自定义PageTransformer,给viewpager设置不同的切换特效,多种特效的欢迎页面...

UIMotionEffect和Home页背景视差效果

当你打开装有iOS7以上的iPhone主屏,默认的背景是一幅蓝色的星空图片。当上下左右翻转iPhone时,有趣的效果将会出现,星空背景也会沿着各个方向发生位移,这与主屏上的各个App Icon形成了一...

UIMotionEffect和Home页背景视差效果

原文链接:http://www.cocoachina.com/ios/20150121/10967.html 0. UIMotionEffect 在iOS7以上的的API中,有...

利用CSS固定背景交替实现视差滚动效果

利用CSS固定背景交替实现视差滚动效果  外部样式表部分 *{  margin:0;  padding:0; } body{  font-family:"Trebuchet MS...

空间背景图的简单的视差效果

空间背景图的简单视差效果 因为不会制作动态效果图,请参考QQ空间下拉

ColorAnimationView 实现了滑动Viewpager 时背景色动态变化的过渡效果

用法在注释中: import android.animation.Animator; import android.animation.ArgbEvaluator; import andro...

[android]so easy实现根据viewpager、edittext、时间使背景动态渐变色效果~

一、前言 *本文是紧接着上文(奇思妙想之实用类ArgbEvaluator)写的。 在这简单回顾下,上文主要提到了一个叫做ArgbEvaluator的一个类,通过他可以灵活实现一些渐变色效果,虽然好...

ViewPager配合的标签背景动画效果

此贴个人的eoe连接 ViewPager配合的标签背景动画效果 http://www.eoeandroid.com/thread-578233-1-1.html 最近需要做一个ViewPager...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ViewPager的视差背景效果
举报原因:
原因补充:

(最多只允许输入30个字)