我正在绘制自定义视图。在此视图中,我使用两个不同的绘制和路径对象绘制到画布。我基本上画了两个重叠的形状。添加alpha后,视图中重叠的部分比图像的其余部分更暗。这是不受欢迎的,但我不确定如何解决它。
这是我的代码的剪辑,以显示我在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分钟......它们显示了我想要的效果。
他们基本上显示这个图像:
添加透明度并获取此图片:UNDESIRED RESED
他们最终得到了这个:渴望的结果
有没有人知道如何获得这种理想的效果?
答案 0 :(得分:12)
如视频中所述,您可以使用Canvas#saveLayerAlpha(....)
。您也可以在不使用它的情况下获得类似的效果。我稍后会讨论。
让我们创建一个示例视图:
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()
时,此位图将传输到屏幕画布,我们在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。
答案 1 :(得分:0)
您可以使用完整的alpha绘制位图中的所有内容,然后更改位图的alpha
(对不起,这是一个评论而非答案,但堆栈溢出不允许我发表评论)