实现效果如下图
实现方法:
1.计算镂空区域的坐标
2.新建一张canvas,绘制半透明蒙版
3.将PorterDuffXfermode设为Clear
4.绘制镂空区域到canvas
具体见代码:
设置要镂空的view:
public void setTarget(View v) {
mTragetView = v;
}
计算镂空区域的坐标:
int[] location = new int[2];
mTragetView.getLocationInWindow(location);
mRectStartPoints = new Point(location[0], location[1]);
rectWidth = mTragetView.getWidth();
rectHeight = mTragetView.getHeight();
绘制蒙版:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBitmap == null) {
mBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_4444);
mTempCanvas = new Canvas(mBitmap);
}
mPaint.setColor(Color.parseColor("#000000"));
mPaint.setAlpha(188);
mTempCanvas.drawRect(0, 0, mTempCanvas.getWidth(), mTempCanvas.getHeight(), mPaint);
mTransparentPaint.setColor(getResources().getColor(android.R.color.transparent));
mTransparentPaint.setXfermode(mPorterDuffXfermode);
mTempCanvas.drawRect(mRectStartPoints.x , mRectStartPoints.y , mRectStartPoints.x + rectWidth
, mRectStartPoints.y + rectHeight, mTransparentPaint);
canvas.drawBitmap(mBitmap , 0 , 0 , mPaint);
}
禁用镂空区域以外的touch事件:
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
//禁用镂空区域以外的触摸事件,如果触摸事件在镂空区域内,执行回调
if ((x > mRectStartPoints.x && x < mRectStartPoints.x + rectWidth) &&
(y > mRectStartPoints.y && y < mRectStartPoints.y + rectHeight)
&& event.getAction() == MotionEvent.ACTION_UP) {
setVisibility(View.GONE);
((ViewGroup) ((Activity) getContext()).getWindow().getDecorView()).removeView(ShowTipsView.this);
if (mListener != null) {
mListener.onTouch();
}
}
return super.onTouchEvent(event);
}
源码地址:github地址