Yes, if you're creating a custom View, you'll need to override onMeasure()
and provide the size that you need it to be.
So, in the method signature for onMeasure
, you'll get two parameters:
- widthMeasureSpec
- heightMeasureSpec
You should use the MeasureSpec
class to get the restrictions you should respect when sizing the View.
/*
* This will be one of MeasureSpec.EXACTLY, MeasureSpec.AT_MOST,
* or MeasureSpec.UNSPECIFIED
*/
int mode = MeasureSpec.getMode(measureSpec);
//This will be a dimension in pixels
int pixelSize = MeasureSpec.getSize(measureSpec);
If you get MeasureSpec.EXACTLY
, then you should use the pixelSize
value for your measured width, no matter what.
If you get MeasureSpec.AT_MOST
, you should just make sure that you set the measured width no greater than pixelSize
.
If you get MeasureSpec.UNSPECIFIED
, you can take as much room as you need. I usually just interpret this as WRAP_CONTENT
.
So your onMeasure()
method may look something like this:
@Override
protected void onMeasure (int widthSpec, int heightSpec) {
int wMode = MeasureSpec.getMode(widthSpec);
int hMode = MeasureSpec.getMode(heightSpec);
int wSize = MeasureSpec.getSize(widthSpec);
int hSize = MeasureSpec.getSize(heightSpec);
int measuredWidth = 0;
int measuredHeight = 0;
if (wMode == MeasureSpec.EXACTLY) {
measuredWidth = wSize;
} else {
//Calculate how many pixels width you need to draw your View properly
measuredWidth = calculateDesiredWidth();
if (wMode == MeasureSpec.AT_MOST) {
measuredWidth = Math.min(measuredWidth, wSize);
}
}
if (hMode == MeasureSpec.EXACTLY) {
measuredHeight = hSize;
} else {
//Calculate how many pixels height you need to draw your View properly
measuredHeight = calculateDesiredHeight();
if (hMode == MeasureSpec.AT_MOST) {
measuredHeight = Math.min(measuredHeight, hSize);
}
}
setMeasuredDimension(measuredWidth, measuredHeight);
}