52

I'm creating a custom widget by extending LinearLayout:

public class MyWidget extends LinearLayout {
    private static Paint PAINT = new Paint(Paint.ANTI_ALIAS_FLAG);
    static {
        PAINT.setColor(Color.RED);
    }

    public MyWidget(Context context) {
        this(context, null);
    }

    public MyWidget(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight()/2, canvas.getWidth()/2, PAINT);
        // never gets called :-(
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        // this gets called, but with a canvas sized after the padding.
    }
}

I can add children just fine, but I'm never getting my custom onDraw() being called. dispatchDraw() gets called, but that seems to have a different canvas (the one that's within the padding. I need to draw on the whole layout area). Is there some flag that needs to get set to get onDraw() called for the layout?

Steve Pomeroy
  • 10,071
  • 6
  • 34
  • 37

1 Answers1

125

You need to call setWillNotDraw(false) in your constructor.

Because by default a layout does not need to draw, so an optimization is to not call is draw method. By calling setWillNotDraw(false) you tell the UI toolkit that you want to draw.

weston
  • 54,145
  • 21
  • 145
  • 203
Romain Guy
  • 97,993
  • 18
  • 219
  • 200
  • Ha! So there was a flag that needed to be set! Thanks :-) – Steve Pomeroy Aug 14 '10 at 00:47
  • 3
    @ Romain Guy, Can you explain why need to add `setWillNotDraw(false)`. Thank you! – Judy Jul 05 '11 at 07:49
  • 22
    Because by default a layout does not need to draw, so an optimization is to not call is draw method. By calling setWillNotDraw(false) you tell the UI toolkit that you want to draw. – Romain Guy Jul 07 '11 at 06:59