【问题标题】:Clearing canvas with Canvas.drawColor()使用 Canvas.drawColor() 清除画布
【发布时间】:2011-01-10 19:40:02
【问题描述】:

我正在尝试成功更改自定义视图的背景图像。图像会改变,但问题是我仍然看到旧图像的痕迹。当我尝试在绘制新图像之前清除画布时,它似乎不起作用。我创建一个位图来存储图像。更改图像时,我在绘制新图像之前调用 Canvas.drawColor() 但旧图像仍然存在。我尝试过 drawColor(0)、drawColor(Color.BLACK)、c.drawColor(0, PorterDuff.Mode.CLEAR),但上述方法均无效。因此,我不得不发布这篇文章以供比我更有经验的人评论。

实际代码如下:

private int bgnd;
private boolean switching;

public void setBgnd(int incoming){
    switching = true;
    switch (incoming){

    case R.drawable.image1:
        bgnd = incoming;
        this.invalidate();
        break;

    case R.drawable.image2:
        bgnd = incoming;
        this.invalidate();
        break;

    }
}



protected void onDraw(Canvas c){
    if(switching == true){
        Bitmap b = BitmapFactory.decodeResource(getResources(), bgnd);
        c.drawColor(0, PorterDuff.Mode.CLEAR);
        c.drawBitmap(b, 0, 0, null);
        switching = false;

    }else{
        Bitmap b = BitmapFactory.decodeResource(getResources(), bgnd);
        c.drawBitmap(b, 0, 0, null);
    }
}

【问题讨论】:

    标签: android canvas ondraw


    【解决方案1】:

    就像你一样,我在如何清除我的多层/surfaceview 应用程序中的顶层/surfaceview 时遇到了困难。经过 2 天的搜索和编码,我找到了自己的方式,这就是我在绘制之前清除画布的方式,您可以在具有多个图层/表面视图时使用它。背景层不会被黑色覆盖,这就是窍门。

    Paint paint = new Paint();
    paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
    canvas.drawPaint(paint);
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC));
    // start your own drawing
    

    【讨论】:

    • 我认为我需要 2 天以上才能弄清楚这一点,而我需要 2 分钟才能到达这里。谢谢奇怪的InAStrangerLand + longdooooo
    【解决方案2】:

    可以使用Canvas的方法drawRGB

    【讨论】:

    • drawRGB() 不会清除 alpha 通道,位图会变得不透明,因此只能在位图为唯一图层或背景图层时使用。还有一个方法 drawARGB(),它也允许处理 alpha 通道。不过没试过。
    • 注意drawRGB只使用drawColor(Color.rgb(r, g, b))
    【解决方案3】:

    您是否也不需要在 onDraw 方法中调用 invalidate(),以便在该 onDraw 中所做的更改在屏幕上更新?

    在你调用 setBgnd 之后,你的 switch 中的 invalidate() 将调用你的 onDraw,但是在你对 Canvas 进行更改之后,没有什么要重绘的。

    【讨论】:

    • 我的印象是调用 invalidate() 会告诉视图调用 onDraw() 并绘制它自己。在这种情况下,将该调用放入方法中会导致它永远循环,如示例中所示:anddev.org/basic_and_simple_2d_drawing_-_animation-t3085.html
    • 啊,你是对的,必须去查一下,developer.android.com/guide/topics/graphics/index.html。抱歉,我的理解不正确。
    • 一开始我也是这么想的。我的问题是,如果 invalidate() 告诉一个视图重绘自己,为什么这个视图不完全重绘自己,直到它稍后在动画中移动?对象的下半部分看起来正确,但另一半仍然是旧表面。
    • 我也尝试过使用 8 位图像,因为我已经读到该问题可能是由于 android 在 32 位图像上遇到的困难引起的。我不认为是这样,我确实发现它没有帮助。我也尝试过 setBackgroundResource() (实际上是在使用画布之前我首先尝试过的)但它也不起作用,即使从 onDraw() 内部调用也是如此。
    【解决方案4】:

    我刚好遇到这个问题。

    我通过重复“..Drawxxx();Post();”来解决它至少3次,效果很好。

    我想,“双缓冲”是原因,有时是“三重缓冲”。我们需要重复绘制以确保每个“缓冲区”都更新..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-21
      • 2012-07-26
      • 2012-07-19
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多