Reputation: 1881
I Have some really strange problems.
First problem is as follow: I read how to override onMeasure(). I did it. I was expecting that when I set width/height in onMeasure that they will be exactly the same in onDraw, but apparently this is not true. Also I except that measuredWidth will be same as width in draw phase, but again it isn't true.
onMeasure could be called many times. On each call I invoke setMeasuredDimension with calculated width and height. So for example, first time my view should be 480 x 245, on second call I recalculate it again, based on parent of course, and it should be 90 x 245.
For my great surprise android somehow is just ignoring everything but the first call. So in this case my final view size is 480 x 245.
Second issue which is as follow: My view height is match_parent, my parent height is 0. So how am I supposed to set right height on onMeasure when I don't know it ?
Any Idea how to make android not to ignore my setMeasureDimensions calls and how to set match_parent ?
Upvotes: 0
Views: 1302
Reputation: 1389
The space that's allocated to your view doesn't depend only on the size you measured, here's a snapshot of the process :
View.onMeasure
gets called during the measurement of your parent. You got your MeasureSpec
that is essentially how much space at most you can take (very summarized).
Given these specs, you determine the size of yourself, logically measuring your own children and calling setMeasuredDimension
A while after, your parent assigns you concrete dimensions, based on what you measured (but this also means it can be different). Then as these will be your dimensions, that's the one you have to use. The callback called at this point is onLayout
, and you shall layout your children in the process, based on the dimensions that were affected to you.
After all this, your View
will be drawn, that is View.dispatchDraw
being called and resulting for simple views to onDraw
. Drawing yourself also means drawing your children if you're a ViewGroup
.
When drawing, the system passes a Canvas
whose dimensions are these of the screen, and using translation and clipping, the canvas is passed along views so that they draw themselves. This avoids allocation during draw. For this reason, if your want to know what space is dedicated to you, you should not use Canvas.getWidth
or Canvas.getHeight
which are the dimensions of the screen, but rather retrieve the clipped dimensions (Canvas.getClipBounds()
)
And finally, when you correctly retrieve the clip bounds, they should usually be the same as your width and height (View.getWidth
or View.getHeight
), but they might be different, for example if the canvas was scaled.
So to summarize :
onMeasure
purpose, is to determine the size of children, so that ViewGroup
can compute they're dezired size.
onLayout
purpose is to affect a width and height to each view, propagating to children.
onDraw
purpose is to render your view.
Upvotes: 1