標籤:android style c ext http color
有時,Android系統控制項無法滿足我們的需求,因此有必要自訂View。具體方法參見官方開發文檔:http://developer.android.com/guide/topics/ui/custom-components.html
一般來說,自訂控制項都會去重寫View的onMeasure方法,因為該方法指定該控制項在螢幕上的大小。
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
onMeasure傳入的兩個參數是由上一層控制項傳入的大小,有多種情況,重寫該方法時需要對計算控制項的實際大小,然後調用setMeasuredDimension(int, int)設定實際大小。
onMeasure傳入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸數值,而是將模式和尺寸組合在一起的數值。我們需要通過int mode = MeasureSpec.getMode(widthMeasureSpec)得到模式,用int size = MeasureSpec.getSize(widthMeasureSpec)得到尺寸。
mode共有三種情況,取值分別為MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。
MeasureSpec.EXACTLY是精確尺寸,當我們將控制項的layout_width或layout_height指定為具體數值時如andorid:layout_width="50dip",或者為FILL_PARENT是,都是控制項大小已經確定的情況,都是精確尺寸。
MeasureSpec.AT_MOST是最大尺寸,當控制項的layout_width或layout_height指定為WRAP_CONTENT時,控制項大小一般隨著控制項的子空間或內容進行 變化,此時控制項尺寸只要不超過父控制項允許的最大尺寸即可。因此,此時的mode是AT_MOST,size給出了父控制項允許的最大尺寸。
MeasureSpec.UNSPECIFIED是未指定尺寸,這種情況不多,一般都是父控制項是AdapterView,通過measure方法傳入的模式。
因此,在重寫onMeasure方法時要根據模式不同進行尺寸計算。下面代碼就是一種比較典型的方式:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getMeasuredLength(widthMeasureSpec, true), getMeasuredLength(heightMeasureSpec, false));
}
private int getMeasuredLength(int length, boolean isWidth) {
int specMode = MeasureSpec.getMode(length);
int specSize = MeasureSpec.getSize(length);
int size;
int padding = isWidth ? getPaddingLeft() + getPaddingRight()
: getPaddingTop() + getPaddingBottom();
if (specMode == MeasureSpec.EXACTLY) {
size = specSize;
} else {
size = isWidth ? padding + mWave.length / 4 : DEFAULT_HEIGHT
+ padding;
if (specMode == MeasureSpec.AT_MOST) {
size = Math.min(size, specSize);
}
}
return size;
}