Custom Android Views like to override onMeasure for a variety of reasons.
Let’s look at an easy and common use case.
We want to create a FrameLayout that is always square.
The first attempt to do so usually looks like the following:
This might appear to work fine in some cases, but let’s look at the following:
Here is what that looks like:
setMeasuredDimension just sets the result of onMeasure; it does not affect how children are measured. The child ImageView is told that its width should each be exactly 320 dips and measures itself accordingly. After that, our SquareFrameLayout decides to change its measurement result.
Also, our SquareFrameLayout really should honor its width and height and only change its children’s widths and heights.
The real solution for this problem involves calculating the appropriate size and making the right measure specs for super.onMeasure:
Run the above layout, and we will see the child Views and our SquareLinearLayout (shown with the white background) properly sized:
If you really want to change the size of the SquareFrameLayout and not just the size of its children, you can alter the resulting setMeasuredDimension calls at the end of onMeasure.
For the basics of MeasureSpec and how Android measures, lays out, and draws Views, the introduction documentation is a great read. It is only a few paragraphs long; I wish I had read it sooner!