Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android View.onDraw() always has a clean Canvas

I am trying to draw an animation. To do so I have extended View and overridden the onDraw() method. What I would expect is that each time onDraw() is called the canvas would be in the state that I left it in and I could choose to clear it or just draw over parts of it (This is how it worked when I used a SurfaceView) but each time the canvas comes back already cleared. Is there a way that I can not have it cleared? Or maybe save the previous state into a Bitmap so I can just draw that Bitmap and then draw over top of it?

like image 732
CaseyB Avatar asked Mar 11 '10 07:03

CaseyB


2 Answers

I'm not sure if there is a way or not. But for my custom views I either redraw everything each time onDraw() is called, or draw to a bitmap and then draw the bitmap to the canvas (like you suggested in your question).

Here is how i do it

class A extends View {

    private Canvas canvas;
    private Bitmap bitmap;

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (bitmap != null) {
            bitmap .recycle();
        }
        canvas= new Canvas();
        bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        canvas.setBitmap(bitmap);
    }
    public void destroy() {
        if (bitmap != null) {
            bitmap.recycle();
        }
    }
    public void onDraw(Canvas c) {
      //draw onto the canvas if needed (maybe only the parts of animation that changed)
      canvas.drawRect(0,0,10,10,paint);

      //draw the bitmap to the real canvas c
      c.drawBitmap(bitmap, 
          new Rect(0,0,bitmap.getWidth(),bitmap.getHeight()), 
          new Rect(0,0,bitmap.getWidth(),bitmap.getHeight()), null);
    }
}
like image 103
dweebo Avatar answered Oct 11 '22 07:10

dweebo


you should have a look here to see the difference between basic view and surfaceView. A surfaceView has a dedicated layer for drawing, which I suppose keeps track of what you drew before. Now if you really want to do it on a basic View, you could try to put each item you draw in an array, like the exemple of itemized overlay for the mapview. It should work pretty much the same way

like image 1
Sephy Avatar answered Oct 11 '22 06:10

Sephy