Creating transparent circle cutout in a View in An

2019-07-06 17:39发布

问题:

I'm trying to create a translucent help overlay to be displayed over my activity's main screen when the user first opens the app. I would like to highlight a button contained in the main layout (and inflated using setContentView), by "cutting out" a section of the overlay which corresponds to the position of the button, and make the cutout transparent.

The overlay is a programmatically-created view (which extends RelativeLayout) which is added to my activity's main FrameLayout, like this:

private void addHelpOverlay(){
    HelpOverlay help = new HelpOverlay(this);
    help.setBackgroundColor(Color.parseColor("#BB222222"));

    mainLayer.addView(help);
}


public class HelpOverlay extends RelativeLayout{

    public HelpOverlay(Context context){
        super(context);
    }

    @Override
    public void dispatchDraw(Canvas canvas){

        canvas.drawColor(Color.parseColor("#BB222222"));

        Paint mPaint = new Paint();
        mPaint.setColor(0xFFFFFF);
        mPaint.setAlpha(0);
        mPaint.setAntiAlias(true);

        canvas.drawCircle(buttonX, buttonY, 100, mPaint);        

        super.dispatchDraw(canvas);
    }
}

The above code doesn't actually show anything, just the translucent layout with no circle cutout. I assume this is because it's just drawing a transparent circle over top of the translucent layout. I'm really struggling to accomplish this, any suggestions would be appreciated!

回答1:

Try adding PorterDuff to your paint object . which will make the specific area to transparent

Paint mPaint = new Paint();
    mPaint.setColor(0xFFFFFF);
    mPaint.setAlpha(0);
    mPaint.setAntiAlias(true);
    mPaint.setColor(Color.TRANSPARENT);
    mPaint.setXfermode(new PorterDuffXfermode(
                PorterDuff.Mode.CLEAR));
    canvas.drawCircle(buttonX, buttonY, 100, mPaint); 

If you get a picth black in the circle area, that must be due to graphic rendering problem , you can enable it using below code right before you declare paint object .

 if (android.os.Build.VERSION.SDK_INT >= 11) {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }

I guess this should fix your issue