2
votes

I have a custom view that implements onMeasure, onSizeChanged and onDraw.

@Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
    super.onSizeChanged(xNew, yNew, xOld, yOld);
    Log.v(TAG, "Measures arrived "+xNew+","+yNew);
}

@Override
protected void onDraw(Canvas canvas) {
    Log.v(TAG, "Time to draw, canvas size "+canvas.getWidth()+","+canvas.getHeight());
}

I add it to a container:

container.addView(customView, new LayoutParams(LayoutParams.MATCH_PARENT, 50)); // fixed height, 50px

My problem is, I don't understand why sometimes the Canvas dimensions don't match the dimensions I get in onSizeChanged once the view has been settled to its final size.

Specifically, in the use case proposed, and focusing only on height, i get:

  • onMeasure: mode: EXACTLY, dimensions 50 (correct)
  • onSizeChanged: size: 50 (correct)
  • onDraw: canvas height: 730px (===screen height)

Why OnDraw's canvas height reports the whole screen? Is it maybe because higher in the hierarchy there may be a clipChildren(false) ?

Note: What I mean by "this happens sometimes" is that this view is a pretty general view (a custom textview from scratch) that I use in very different places: inside scrollviews, inside adapters, deep-nested, etc..

1
I recall reading somewhere that canvas.getBounds() is sometimes the appropriate method to call, but I've not tried it where some parent view had clipChildren="false". You might consider storing the values passed to onSizeChanged() and using those in onDraw().Karakuri
@Karakuri yeah , that's what i'm doing at the moment, they are the ones that always seem correct regardless where the view is placed, however I was curious about the canvas.height thing. I appreciate the tip on Canvas.getBounds(), that's probably the correct answer, thinking about it, it makes all sense that if the clip region has been altered by ie. setClipChildren, the passed canvas would cover all height, but the real height is that of getBounds() :) gonna make the test!rupps
@karakuri Bingo! The correct sizes are indeed available in canvas.getClipBounds() . If you post it as the answer i'd gladly accept it. canvas_height=729, onSizeChanged_height=50, bounds Rect(0, 50 - 0, 50). (Interestingly, if the width is MATCH_PARENT, the clip region Width is 0)rupps

1 Answers

1
votes

Using canvas.getClipBounds() should give the appropriate sizes, even if the canvas width and height are actually larger.