實現(xiàn)一個自定義View我們需要繼承View或viewgroup,并且實現(xiàn)三個方法痹仙。
onMeasure(int widthMeasureSpec, int heightMeasureSpec) 測量的方法有三種測量模式,這里的值是獲取的父view給的測量值
MeasureSpec.UNSPECIFIED 父容器對子View沒有任何約束漆魔,子 View 可以按自身需要根悼,任意大小。
MeasureSpec.AT_MOST 大小由view自身確定庶柿,不能超過父容器大小。wrap_content對應(yīng)的就是它
MeasureSpec.EXACTLY 固定寬高,寬高都已經(jīng)可以確定了秽浇,不能超過指定的大小浮庐。 match_parent和寫死的大小對應(yīng)它
通過 getMode getSize 獲得當(dāng)前的模式和size
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
注意在自定義view中獲取子控件寬高都需要使用getMeasuredHeight|getMeasuredWidth
onLayout(int l, int t, int r, int b)
測量完后調(diào)用的方法,lt代表左上角的XY rb代表右下角的XY
**onDraw(Canvas canvas) **
知道了大小和怎么擺放現(xiàn)在就是畫上去了
ViewGroup繼承于View的子類 一個容器view繼承它必須實現(xiàn)onLayout方法。調(diào)用順序和View是一致的
下面是一段模仿LinearLayout的代碼
public class TestGroup extends ViewGroup {
public TestGroup(Context context) {
super(context);
}
public TestGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TestGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.i("jinwei", "onMeasure");
measureChildren(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.AT_MOST &&
heightMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(getWidthCount(), getHeightCount());
} else if (widthMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(getMeasuredWidth(), heightSize);
} else if (heightMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(widthSize, getHeightCount());
} else {
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.i("jinwei", "onLayout");
int count = getChildCount();
//記錄當(dāng)前的高度位置
int width = l;
for (int i = 0; i < count; i++) {
View childAt = getChildAt(i);
int measuredHeight = childAt.getMeasuredHeight();
int measuredWidth = childAt.getMeasuredWidth();
childAt.layout(0, width, measuredWidth, measuredHeight + width);
width += measuredHeight;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.i("jinwei", "onDraw");
}
private int getHeightCount() {
int count = getChildCount();
int maxHeight = 0;
for (int i = 0; i < count; i++) {
int height = getChildAt(i).getMeasuredHeight();
maxHeight += height;
}
return maxHeight;
}
private int getWidthCount() {
int count = getChildCount();
int maxWidth = 0;
for (int i = 0; i < count; i++) {
int width = getChildAt(i).getMeasuredWidth();
maxWidth += width;
}
return maxWidth;
}
}