Question

I'm trying to figure out how to "cut-out a feathered hole" in an ImageView.

The reasoning is, I am creating a tutorial, and I want the whole screen dim. That's easy enough to do by placing a black image with alpha around 50%. Next I want to cut a hole into that overlay, so you can more clearly see what's underneath it. The goal in mind is to highlight buttons and things for the user to click on, so they learn what to do.

When I did this before in ActionScript / Flash, it was easy to just put a dim-alpha over the screen, then create a circle, scale it's X & Y to match the object I want to highlight, then add a filter to it with it's blend mode set to SUBTRACT. This subtractive circle/oval could also be told to accept mouse clicks, and the hole thing worked great.

In android, I can't seem to see how to subtract from views. I can see people using color filters to add to a view or change the colors.

So, unless I am missing the boat, how do you subtract?

Was it helpful?

Solution

You need to write a custom Drawable class and assign it to your ImageView. Then you can do this easily in the draw method like this:

class MyDrawable extends Drawable {

    @Override
    public void draw(Canvas canvas) {
        Path path = new Path();
        path.setFillType(FillType.EVEN_ODD);

        // This will create a full screen rectangle.
        path.addRect(<screen size rect here>, Path.Direction.CW);

        // This will punch a hole in it
        path.addCircle(<x>, <y>, <radius>, Path.Direction.CCW);

        // Now draw everything on the Canvas
        Paint paint = new Paint();
        paint.setColor(<dim color here>);
        canvas.drawPath(path, paint);
    }

To make it work nicely when highlighting, you can pass the View you want to highlight in this Drawable's constructor. Then you can determine the position of the view using:

int[] position = new int[2];
view.getLocationOnScreen(position);

Use this and the view's height and width to determine the size and position of the circle.

I don't know if this will work, but you can also try feathering the cutout by doing this:

paint.setMaskFilter(new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top