BackgroundViewPager实现桌面launch移动,viewpage切换背景更随移动改变。
下面介绍项目三个比较重要的函数: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));
}