最近在擼新的東西玩,自定義View我也算是半個老司機了。首先在onMeasure中處理了wrap_content的情況,然後我驚奇的在log中發現,我測量出來的結果竟然是1080?這是什麼操作?後來除錯發現測量寬度時進入了精確模式,沒跑了肯定是match_parent。我是怎麼把View新增到父View的呢?程式碼如下:
ll_container!!.addView(v)
複製程式碼
這是一個LinearLayout,不說多的點進addView看一下:
public void addView(View child) {
addView(child, -1);
}
public void addView(View child, int index) {
if (child == null) {
throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
}
LayoutParams params = child.getLayoutParams();
if (params == null) {
params = generateDefaultLayoutParams();
if (params == null) {
throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
}
}
addView(child, index, params);
}
複製程式碼
可以看到首先addView(View)方法呼叫了過載方法,並在在新增之前判斷了LayoutParams,如果為null則生成一個,不為null則新增到ViewGroup中。我這裡沒有設定LayoutParams,所以必定為null,那看一下生成引數的程式碼吧:
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
複製程式碼
納尼???看到這真是黑人問號了,倆wrap_content進入了exactly測量模式,除非Android系統爆炸還差不多。後來突然想起來Java有一種玩意叫做後期繫結,可能是LinearLayout複寫了這個生成引數的方法,點進LinearLayout搜尋了一下,果然如此:
protected LayoutParams generateDefaultLayoutParams() {
if (mOrientation == HORIZONTAL) {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
} else if (mOrientation == VERTICAL) {
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
}
return null;
}
複製程式碼
沒辦法,剛好設定的vertical方向,果然width設定了match_parent。看來以後還是要多瞭解一下ViewGroup。