Android开源项目 BackgroundViewPager 分析

BackgroundViewPager实现桌面launch移动,viewpage切换背景更随移动改变。

项目下载地址:https://github.com/MoshDev/BackgroundViewPager

下面介绍项目三个比较重要的函数:onPageScrolled,dispatchDraw和processBitmap


@Override
	public void onPageScrolled(int position, float positionOffset,
			int positionOffsetPixels) {
		super.onPageScrolled(position, positionOffset, positionOffsetPixels);
		Log.i(TAG,"onPageScrolled(int position, float positionOffset,int positionOffsetPixels)");
		float over = (position * getWidth()) + positionOffsetPixels;
		mBackgroundX = -over * fraction;//每移动时产生偏移量
	}
监听Viewpage的滑动,得出偏移量mBackgroundX


说一下ViewGroup的dipatchDraw函数:

dispatchDraw()主要是分发给子组件进行绘制,我们通常定制组件的时候重写的是onDraw()方法。值得注意的是ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法,或者自定制一个Drawable

@Override
	protected void dispatchDraw(Canvas canvas) {
		if (mBitmap != null) {
			int save = canvas.save();
			Rect rect = canvas.getClipBounds();//获取控件需要重新绘制的区域
			canvas.translate(rect.left, rect.top);
			canvas.drawBitmap(mBitmap, mBackgroundOrginalRect, new RectF(
					mBackgroundX, 0, mBackgroundNewRect.right+mBackgroundX,
					mBackgroundNewRect.bottom), null);
			canvas.restoreToCount(save);
		}
		super.dispatchDraw(canvas);
	}

最关键的一句:

canvas.drawBitmap(mBitmap, mBackgroundOrginalRect, new RectF(
					mBackgroundX, 0, mBackgroundNewRect.right+mBackgroundX,
					mBackgroundNewRect.bottom), null);
把要移动的背景图片画到 left为mBackgroundX, top为0, right为mBackgroundNewRect.right+mBackgroundX, bottom为mBackgroundNewRect.bottom的矩形里。

mBackgroundX必定小于等于0.



/**
	 * 完成原位图缩放
	 */
	private void processBitmap() {
		int w = getWidth();
		int h = getHeight();
		boolean isDrawable = false;
		if (mBitmapRes > -1) {//有默认图片
			Drawable drawable = getResources().getDrawable(mBitmapRes);

			if (drawable instanceof BitmapDrawable) {
				mBitmap = ((BitmapDrawable) drawable).getBitmap();
			} else {
				isDrawable = true;
				mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
				Canvas canvas = new Canvas(mBitmap);
				drawable.setBounds(getLeft(), getTop(), getRight(), getBottom());

				drawable.draw(canvas);

			}
		}
		if (mBitmap == null || w == 0 || h == 0) {
			return;
		}
		float count = 1;
		if (getAdapter() != null && getAdapter().getCount() > 0) {
			count = getAdapter().getCount();
		}
		int imgWidth = mBitmap.getWidth();
		int imgHeight = mBitmap.getHeight();
		float ratio = (float) imgWidth / (float) imgHeight;
		float width = w * mFactor;
		float height = (isDrawable ? imgHeight : width / ratio);
		mBackgroundOrginalRect = new Rect(0, 0, imgWidth, imgHeight);//原图的矩阵
		mBackgroundNewRect = new RectF(0, 0, width, height);//3倍的屏幕宽度的矩阵,宽高比例与原图相同,之所以是3,因为有3页
		Rect sizeRect = new Rect(0, 0, w * mFactor, h);//3被屏幕宽度,屏幕高度
		fraction = ((float) sizeRect.width() / (float) ((float) w * (float) count));
	}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值