今天这个项目的名称叫做擦掉乌云你会发现生活的美好!额,不闷骚了!其实就是底层发一张美女的图片,再覆盖一层灰色(模拟乌云),同时触摸监听,使手指触摸的地方的那一层灰色消失(类似于乌云被擦掉了);ok,我们看一下效果图。不满意请上别处!
就是类似的效果!代码熟悉后图片你可以随便换哈!
要实现这种效果,我们用到了Xfermode这个类!对于这个的应用,官方的案例给了很好的说明!
我们今天要用的就是,DstOUt这种模式,我们先绘制“乌云”层,再利用Paint对象的setXfermode(new PorterDuffXfermode(Mode.DST_OUT));绘制
手划过的线,这样线与乌云重合的部分就消失了,达到了擦去的效果!
我们要自定义一个View,老生常谈一下基本步骤!
1,自定义属性;2,在构造方法中拿到自定义属性的值;3,重写onMeasure方法;4,重写onDraw()方法
今天的代码没有1,和2,;
废话不多说,附上今天的代码!
第一步,初始化,画笔和线条(即实例化)
public CustomViewDustOff(Context context) {
this(context, null, 0);
}
public CustomViewDustOff(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomViewDustOff(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
//初始化画笔,线条
private void init(){
outPaint=new Paint();
outPaint.setAntiAlias(true);
outPaint.setStyle(Paint.Style.STROKE);
outPaint.setStrokeWidth(30);
outPaint.setXfermode(new PorterDuffXfermode(Mode.DST_OUT));
mPath=new Path();
}
第二步重写onMeasure方法中
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width=getMeasuredWidth();
int height=getMeasuredHeight();
//获得底层的图片的位图对象
backBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.beauty);
//根据位图和空间的比值,设置矩阵的属性
float scale=Math.min(width*1.0f/backBitmap.getWidth()*1.0f, height*1.0f/backBitmap.getHeight()*1.0f);
mMatrix=new Matrix();
mMatrix.setScale(scale, scale);
//初始化,位图和画笔用于实现擦乌云的效果!
mBitmap=Bitmap.createBitmap(width, height, Config.ARGB_8888);
mCanvas=new Canvas(mBitmap);
//绘制“乌云”
mCanvas.drawColor(Color.parseColor("#c0c0c0"));//绘制灰尘
}
第三部重写onDraw方法
@Override
protected void onDraw(Canvas canvas) {
//绘制底图,根据矩阵进行适当的缩放
canvas.drawBitmap(backBitmap,mMatrix,null);
//画线,即实现擦乌云的效果
drawPath();
//将现实了擦乌云效果的为图对象,绘制在底图上面
canvas.drawBitmap(mBitmap, 0, 0, null);
super.onDraw(canvas);
}
private void drawPath(){
mCanvas.drawPath(mPath, outPaint);
}
重写onTouchEvent()方法,设置触摸监听!
@Override
public boolean onTouchEvent(MotionEvent event) {
float postX=event.getX();
float postY=event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX=postX;
lastY=postY;
mPath.moveTo(postX, postY);
break;
case MotionEvent.ACTION_MOVE:
float dx=Math.abs(postX-lastX);
float dy=Math.abs(postY-lastY);
if(dx>3||dy>3){
mPath.lineTo(postX, postY);
lastX=postX;
lastY=postY;
invalidate();
}
break;
}
return true;
}
private void drawPath(){
mCanvas.drawPath(mPath, outPaint);
}