高级UI汇总
eniorUI05_Paint_Xfermode模式
##1 Effect Picture
##2 Demo
SeniorUI05_GuaGuaCardActivity
##3 Requirement
刮刮卡效果:显示一张图片,手势触摸滑动露出图片后面覆盖的内容
##4 Theory
- 自定义View,同一位置画两张图片,上层位置手指划过路径实现透明,从而实现“刮”的效果
- 利用xfermode合成上层图片
- 上层图片为src,创建一个与src等宽高无内容透明图片dst
- 手指触摸的路径画到dst上
- 利用xfermode的SRC_OUT将src和dst合成,结果是src中去掉dst的图片内容,最终生成我们想要的刮刮卡效果
##5 Core Code
public class GuaGuaCardView_SRCOUT extends View {
private Paint mBitPaint;
private Bitmap BmpDST,BmpSRC,BmpText;
private Path mPath;
private float mPreX,mPreY;
public GuaGuaCardView_SRCOUT(Context context, AttributeSet attrs) {
super(context, attrs);
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mBitPaint = new Paint();
mBitPaint.setColor(Color.RED);
mBitPaint.setStyle(Paint.Style.STROKE);
mBitPaint.setStrokeWidth(45);
BmpText = BitmapFactory.decodeResource(getResources(),R.drawable.guaguaka_text1,null);
BmpSRC = BitmapFactory.decodeResource(getResources(), R.drawable.guaguaka,null);
BmpDST = Bitmap.createBitmap(BmpSRC.getWidth(), BmpSRC.getHeight(), Bitmap.Config.ARGB_8888);
mPath = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(BmpText,0,0,mBitPaint);
int layerId = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
//先把手指轨迹画到目标Bitmap上
Canvas c = new Canvas(BmpDST);
c.drawPath(mPath,mBitPaint);
//然后把目标图像画到画布上
canvas.drawBitmap(BmpDST,0,0,mBitPaint);
//计算源图像区域
mBitPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
canvas.drawBitmap(BmpSRC,0,0,mBitPaint);
mBitPaint.setXfermode(null);
canvas.restoreToCount(layerId);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
mPath.moveTo(event.getX(),event.getY());
mPreX = event.getX();
mPreY = event.getY();
return true;
case MotionEvent.ACTION_MOVE:
float endX = (mPreX+event.getX())/2;
float endY = (mPreY+event.getY())/2;
mPath.quadTo(mPreX,mPreY,endX,endY);
mPreX = event.getX();
mPreY =event.getY();
break;
case MotionEvent.ACTION_UP:
break;
}
postInvalidate();
return super.onTouchEvent(event);
}
}