我正在绘制自定义 View 。在此 View 中,我使用两个不同的绘制对象和路径对象将其绘制到 Canvas 上。我基本上是在画两个重叠的形状。添加Alpha后,重叠的 View 部分比图像的其余部分更暗。这是不希望的,但我不确定如何解决。
这是我的代码的一部分,以显示我如何在NewButtonView.java中使用Alpha
Paint paint = new Paint();
int color = 0x33ffffff;
int borderColor = 0xFF000000;
paint.setColor(color);
paint.setAntiAlias(true);
paint.setStrokeWidth(strokeWidth);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStyle(Paint.Style.FILL);
进入Google I/O video大约31分钟...它们显示了我想要的效果。
他们基本上显示此图像:
添加透明度并获得此图像:不需要的结果
他们最终得到这个:期望的结果
有谁知道如何获得这种期望的影响?
最佳答案
如视频中所提到的,您将为此使用Canvas#saveLayerAlpha(....)
。您也可以不使用它而获得类似的效果。稍后再讨论。
让我们创建一个示例 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();
}
}
怎么了:
saveLayerAlpha(....)
时分配了屏幕外位图。 canvas.restore()
时,此位图将传输到屏幕上的 Canvas ,我们在saveLayerAlpha(....)
中提供的alpha值将应用于屏幕外的位图。 (我认为)以下是在不使用
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);
}
}
}
输出:
仅供引用,上图中的基本容器是
LinearLayout
,背景设置为此jpeg:Link。并且,将drawable用作SampleView的背景:
// Just a random image to 'see' the difference
setBackground(getResources().getDrawable(R.drawable.hor_lines));
取自:here。