一、自定義組件大小的設置
不管你怎麼設置,自定義組件似乎總是match_parent。我們需要覆蓋onMeasure方法,並在其內正確設置組件大小。
[java]
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//注意:為盡可能簡潔本文只討論EXACTLY和AT_MOST模式
int mode = MeasureSpec.getMode(widthMeasureSpec);
if(mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
this.widthMeasureSpec = widthMeasureSpec;
this.heightMeasureSpec = heightMeasureSpec;
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
} else if(mode == MeasureSpec.UNSPECIFIED) {
Log.d("WOGU", "mode=UNSPECIFIED");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
二、自定義組件內的組件的大小設置
除了覆蓋onMeasure還需覆蓋onLayout,在其內設置子元素的大小。
[java]
public class MyViewGroup extends ViewGroup {
protected int widthMeasureSpec, heightMeasureSpec;
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if(changed) {
View view = getChildAt(0);
//measure將觸發View的onMeasure。
//widthMeasureSpec包括尺寸和模式
//int width = MeasureSpec.getSize(widthMeasureSpec);
//int height = MeasureSpec.getSize(heightMeasureSpec);
//int mode = MeasureSpec.getMode(widthMeasureSpec);
//mode的可能值MeasureSpec.AT_MOST,MeasureSpec.EXACTLY,MeasureSpec.UNSPECIFIED
//這裡只是簡單的在onMeasure中記錄widthMeasureSpec和heightMeasureSpec
//其實MeasureSpec提供了根據sizet和模式合成widthMeasureSpec,heightMeasureSpec的方法
//int widthMeasureSpec = MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY);
//int heightMeasureSpec = MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY);
view.measure(widthMeasureSpec, heightMeasureSpec);
view.layout(0, 0, getWidth(), getHeight());
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
this.widthMeasureSpec = widthMeasureSpec;
this.heightMeasureSpec = heightMeasureSpec;
...
}
}