0

Okay, so I'm trying to draw to a canvas on Android from outside of the onDraw method.

It's just easiest to show my code:

public class TestActivity extends Activity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Paint p = new Paint();
    p.setColor(Color.GREEN);
    Panel a = new Panel(this,150,150,50,p);
    a.drawThing();
   setContentView(a);

}
class Panel extends View{
    private float radius, x, y;
    private Canvas CAN; 
    private Paint p;
    public Panel(Context context, float x, float y, float radius, Paint p){
        super(context);
        this.x = x;
        this.y = y;
        this.radius = radius;
        this.p = p;

    }
    @Override
    public void onDraw(Canvas canvas){
        super.onDraw(canvas);
        CAN = canvas;

    }

    public void drawThing(){
        CAN.drawCircle(x, y, radius, p);
    }
}
}

Do you see what I'm trying to do? But for some reason it throws a NullPointerException

Vivek Kalkur
  • 2,200
  • 2
  • 21
  • 40
Jordan Force
  • 11
  • 1
  • 4

3 Answers3

4

Many of the graphics resources are explicitly freed/released after they've been used. I'm not exactly sure why they do this, but whatever the reason, they don't you to do what you're trying.

Instead of drawing outside of the onDraw method, use some kind of flag to change what the onDraw method is doing. When you want to draw some specific thing, you can set the right flag, and call invalidate().

@Override
public void onDraw(Canvas canvas){
    super.onDraw(canvas);
    if (doThing) {
        canvas.drawCircle(x, y, radius, p);
    }
}

EDIT
Something else to consider is drawing to and "off-scrren" source. This means using some kind of graphics representation like a bitmap as a buffer that you can draw to in other code. This won't update your gui, but it will give you the chance to do some heavy duty drawing without locking up the user's device. Once you are done drawing to the bitmap (or whatever) you can invalidate your view and draw it to the screen in the onDraw(Canvas) method.

mtmurdock
  • 12,756
  • 21
  • 65
  • 108
  • Thanks. Drawing offscreen is how I did it. But I still don't know how and where invalidate should be called? – SMUsamaShah Jun 12 '16 at 19:33
  • invalidate should get called anywhere in your code where you know that the information on the screen is no longer correct, and your view needs to be redrawn. So if you're making a data view of some kind, you can invalidate when the data has changed. If you're making a game, you can invalidate once every iteration of the game loop. Exactly when this is will depend on what you're trying to do. – mtmurdock Jun 15 '16 at 23:05
1

I'm pretty sure that the null pointer happens because you're calling drawSomething before onDraw ever gets called. So CAN is null.

Marty Miller
  • 913
  • 2
  • 11
  • 27
0

You can draw onto canvas outside of the onDraw. See this Can we have two canvases in an activity ? (OR) Having a canvas outside the onDraw() is not working for more info.

Community
  • 1
  • 1
eyespyus
  • 1,576
  • 19
  • 20