Adding a spotlight overlay in Android

android.png

Often there's a need to provide an overlay to your view with a spotlight to highlight a particular area. These are commonly used in the context of map views or tutorials.

First subclass RelativeLayout:

public class MaskView extends RelativeLayout
{
Paint _paint;
Button _spotlightButton;
PorterDuffXfermode _blender;
LayoutParams _spotlightButtonLayout;
Matrix _matrix;
Context _context;
int _spotlightX;
int _spotlightY;
float _scale;
public MaskView(Context context)
{
super(context);
_context = context;
}
public MaskView(Context context, AttributeSet attrs)
{
super(context, attrs);
_context = context;
}
public MaskView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
_context = context;
}
}

Set your X,Y and set up your paint object:

public void init(Point point, String buttonText, float scale)
{
SetHardwareAccelerated(true);
_spotlightX = point.x;
_spotlightY = point.y;
_scale = scale;
_blender = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
_paint = new Paint();
_paint.setColor(getResources().getColor(android.R.color.white));
_paint.setAlpha(0);
_paint.setXfermode(_blender);
_paint.setAntiAlias(true);
addButton(buttonText);
}

Then override the dispatchDraw method and draw your circle:

@Override
protected void dispatchDraw(Canvas canvas)
{
canvas.drawColor(Color.parseColor("#8C000000"));
_matrix = new Matrix();
_matrix.postScale(_scale, _scale, _spotlightX, _spotlightY);
canvas.setMatrix(_matrix);
canvas.drawCircle(_spotlightX, _spotlightY, 200, _paint);
canvas.setMatrix(new Matrix());
super.dispatchDraw(canvas);
}

Using your new layout:

_maskView = new MaskView(this);
_maskView.init(new Point(width / 2, height / 2), "Dismiss mask view", 1f);
_maskView.getMaskButton().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view)
{
_maskView.setVisibility(View.GONE);
}
});

And that is it! Full code on GitHub at https://github.com/pricimus/Mask