如何在安卓设备上使画布绘制区域透明?

15

我希望使 Canvas 区域透明,因为我想在它后面添加一张图片,以便 Canvas 操作发生在图片之上。以下是我的 Canvas 代码:

public class Panel extends SurfaceView implements SurfaceHolder.Callback {

private ViewThread mThread;
private ArrayList<Element> mElements = new ArrayList<Element>();

public Panel(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    getHolder().addCallback(this); 
    mThread = new ViewThread(this); 
} 


public void doDraw(Canvas canvas) {
    canvas.drawColor(Color.TRANSPARENT);
    synchronized (mElements) {
        for (Element element : mElements) {
            element.doDraw(canvas);
        }
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    // TODO Auto-generated method stub
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    if (!mThread.isAlive()) {
        mThread = new ViewThread(this);
        mThread.setRunning(true);
        mThread.start();
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    if (mThread.isAlive()) {
        mThread.setRunning(false);
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    synchronized (mElements) {
        mElements.add(new Element(getResources(), (int) event.getX(), (int) event.getY()));
    }
    return super.onTouchEvent(event);
}

}

如何实现它,任何相关示例代码都将非常有帮助。谢谢。


嘿@Karthik,你找到解决办法了吗?我过去一周一直在尝试解决同样的问题。 - Sumeet Gohil
9个回答

26

我通过这个得到了输出

 public Panel(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    this.setBackgroundColor(Color.TRANSPARENT);                 
    this.setZOrderOnTop(true); //necessary                
    getHolder().setFormat(PixelFormat.TRANSPARENT); 
    getHolder().addCallback(this); 
    mThread = new ViewThread(this); 

} 

有没有更好的解决方案来替换setZOrderOnTop,因为它会导致画布上的其他对象无法正常工作? - King Of The Jungle

14

如果您想要一个透明背景的画布,您需要为

mCanvas = new Canvas(mBackgroundBitmap);

配置位图格式为 Bitmap.Config.ARGB_4444 的背景图片,并使用像 0x00000000 这样的颜色表示透明。

    Bitmap mBackgroundImage = Bitmap.createBitmap(Size, Size,
                    Bitmap.Config.ARGB_4444);
    mCanvas = new Canvas(mBackgroundImage);

希望这有所帮助!我的画布非常透明 :D 好开心!


1
当我这样做时,我的布局的渲染视图开始隐藏整个布局中的所有元素。我该怎么办?提前致谢。 - Febin Mathew
2
小更新:最好使用ARGB_8888,因为ARGB_4444现在已经被弃用了。来源:https://developer.android.com/reference/android/graphics/Bitmap.Config - Hibbem

10
canvas.drawColor(Color.argb(0, 255, 255, 255));

第一个属性是alpha通道,其他的是RGB颜色。

或者

canvas.drawColor(Color.TRANSPARENT);

它是否正确绘制了其他颜色?你的SurfaceView的背景颜色是什么? - Awais Tariq
它可以正确地绘制其他颜色,但当我尝试时,我只得到黑色背景。我该如何摆脱这个问题? - Karthik
1
如果您还没有添加,请尝试在XML中首先添加SurfaceView的透明背景。然后它可能会正常工作。 - Awais Tariq

8

这会使画布透明,对我来说很有效 :)

canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.OVERLAY);

5
在您的onDraw()方法中添加以下内容:
canvas.drawColor(0x00AAAAAA);

这将使您的canvas透明,background View将会显示。


3
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)

对我来说使用起来很好,使用的是

override fun onFinishInflate() {
    super.onFinishInflate()
    setZOrderOnTop(true)
    holder.setFormat(PixelFormat.TRANSLUCENT)
    isFocusable = true
    holder.addCallback(surfaceCallback)
}

非常感谢,这是唯一正确运行的解决方案。 - King Of The Jungle

2
你可以创建一个与画布大小相同的位图。使用Color.TRANSPARENCY擦除位图的所有颜色,并将其设置为画布位图:
Bitmap transparentBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(),
Bitmap.Config.ARGB_8888);
transparentBitmap.eraseColor(Color.TRANSPARENT);
canvas.setBitmap(transparentBitmap);

不支持的操作异常 - Alberto M

1
将画布视图的背景颜色设置为 #00000000。

1

嗯,我不确定如何绘制透明画布,但在您的情况下,您可以进行一些调整,使用背景图像本身来绘制画布。

然后,您可以用手指在上面绘制/涂鸦。

代码示例:

        BitmapDrawable bd = (BitmapDrawable)<YOUR_ACTIVITY>.this.getResources().getDrawable(R.drawable.<DRAWBLE_ID>);
        Bitmap b = bd.getBitmap();

        mBitmap = Bitmap.createBitmap(b,0,0,100,100); // This line is required only if you wanna some change in the bitmap you created
        mCanvas = new Canvas(mBitmap);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接