標籤:android style blog ar io color os sp strong
自訂控制項都會去重寫View的onMeasure方法,因為該方法指定該控制項在螢幕上的大小。
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
onMeasure傳入的兩個參數是由上一層控制項傳入的大小,有多種情況,重寫該方法時需要對計算控制項的實際大小,然後調用setMeasuredDimension(int, int)設定實際大小。
onMeasure傳入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸數值,而是將模式和尺寸組合在一起的數值。
常用的三個函數
int getMode(int measureSpec)//根據提供的測量值(格式)提模數式(上述三個模式之一)int getSize(int measureSpec)//根據提供的測量值(格式)提取大小值(這個大小也就是我們通常所說的大小)int makeMeasureSpec(int size,int mode)//根據提供的大小值和模式建立一個測量值(格式)
得到模式:
int mode = MeasureSpec.getMode(widthMeasureSpec)
得到尺寸:
int size = MeasureSpec.getSize(widthMeasureSpec)
Mode
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方法傳入的模式。
Code
控制項根據橫豎屏、螢幕大小自適應:
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); if (0 == mRatioWidth || 0 == mRatioHeight) { setMeasuredDimension(width, height); } else { if (width < height * mRatioWidth / mRatioHeight) { setMeasuredDimension(width, width * mRatioHeight / mRatioWidth); } else { setMeasuredDimension(height * mRatioWidth / mRatioHeight, height); } } } public void fitWindow(int width, int height) { if (width < 0 || height < 0) { throw new IllegalArgumentException("Size cannot be negative."); } mRatioWidth = width;//螢幕寬 mRatioHeight = height;//螢幕高 requestLayout();//促使調用onMeasure }我是天王蓋地虎的分割線
Android -- MeasureSpec