As mentioned in the video, you would use Canvas#saveLayerAlpha(....)
for this. You can also get a similar effect without using it. I'll discuss that later on.
Let's create a sample view:
public class SampleView extends View {
// Declare Paint objects
Paint paintColor, paintBorder;
public SampleView(Context context) {
super(context);
// Initialize and set up Paint objects
paintColor = new Paint();
paintBorder = new Paint();
paintColor.setAntiAlias(true);
paintBorder.setAntiAlias(true);
paintBorder.setColor(Color.BLACK);
paintBorder.setStyle(Style.STROKE);
paintBorder.setStrokeWidth(10);
// Just a random image to 'see' the difference
setBackground(getResources().getDrawable(R.drawable.hor_lines));
}
@Override
protected void onDraw(Canvas canvas) {
// Save layer alpha for Rect that covers the view : alpha is 90 / 255
canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), 90,
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
// Draw first circle, and then the border
paintColor.setColor(Color.RED);
canvas.drawCircle(getWidth() / 3, getHeight() / 2,
getWidth() / 4 - 20, paintColor);
canvas.drawCircle(getWidth() / 3, getHeight() / 2,
getWidth() / 4 - 15, paintBorder);
// Draw second circle, and then the border
paintColor.setColor(Color.BLUE);
canvas.drawCircle(2 * getWidth() / 3, getHeight() / 2,
getWidth() / 4 - 20, paintColor);
canvas.drawCircle(2 * getWidth() / 3, getHeight() / 2,
getWidth() / 4 - 15, paintBorder);
// Finally, restore the canvas
canvas.restore();
}
}
What happens:
An off-screen bitmap is allocated when saveLayerAlpha(....)
is called.
All drawing operations happen on this bitmap.
When canvas.restore()
is called, this bitmap is transferred to the on-screen canvas, and the alpha value we supplied in saveLayerAlpha(....)
is applied to the off-screen bitmap.
(I think) The following is an equivalent way of creating this effect without using saveLayerAlpha(....)
:
public class SView extends View {
Paint paintColor, paintBorder, paintAlpha;
Bitmap toDrawOn;
public SView(Context context) {
super(context);
paintAlpha = new Paint();
paintAlpha.setColor(Color.parseColor("#90FFFFFF"));
paintAlpha.setAntiAlias(true);
....
....
}
@Override
protected void onDraw(Canvas canvas) {
if (toDrawOn == null) {
// Create a new Bitmap
toDrawOn = Bitmap.createBitmap(getWidth(), getHeight(),
Config.ARGB_8888);
// Create a new Canvas; drawing operations
// will happen on 'toDrawOn'
Canvas offScreen = new Canvas(toDrawOn);
// First circle
paintColor.setColor(Color.RED);
offScreenCanvas.drawCircle(getWidth() / 3, getHeight() / 2,
getWidth() / 4 - 20, paintColor);
offScreenCanvas.drawCircle(getWidth() / 3, getHeight() / 2,
getWidth() / 4 - 15, paintBorder);
// Second circle
paintColor.setColor(Color.BLUE);
offScreenCanvas.drawCircle(2 * getWidth() / 3, getHeight() / 2,
getWidth() / 4 - 20, paintColor);
offScreenCanvas.drawCircle(2 * getWidth() / 3, getHeight() / 2,
getWidth() / 4 - 15, paintBorder);
// Draw bitmap 'toDrawOn' to canvas using 'paintAlpha'
canvas.drawBitmap(toDrawOn, 0, 0, paintAlpha);
} else {
// 'toDrawOn' is not null; draw it
canvas.drawBitmap(toDrawOn, 0, 0, paintAlpha);
}
}
}
Output:

Just for reference, the base container in the image above is a LinearLayout
with background set to this jpeg: Link.
And, the drawable used as the background of SampleView:
// Just a random image to 'see' the difference
setBackground(getResources().getDrawable(R.drawable.hor_lines));
is taken from: here.