这是我的前一篇,自定义View篇
对于ViewGroup来说就是一个里面放了许多的View的东西。所以想要自定义一个ViewGroup比自定义View要稍微复杂一点。
1.重写onMeasure()方法
2.重写onLauyout()方法
3.处理触摸事件
onMeasure() 跟自定义View一样,需要测量好并给其设置测量好的宽高,但ViewGroup的跟View不太一样的地方在于,View需要测量的是自己,而ViewGroup则是测量自己里面的子View,并根据子View的测量来设置自己的宽高。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
height = 0;
width = MeasureSpec.getSize(widthMeasureSpec);
for (int i = 0; i < getChildCount(); i++) {
//遍历子View,并测量
View child = getChildAt(i);
measureChild(child, widthMeasureSpec, heightMeasureSpec);
height += child.getMeasuredHeight();
}
setMeasuredDimension(width, height);
}
这里我写的是ViewGroup的宽是固定的(match_parent),而高则是所有子View的高之和(相当于wrap_content)。所有根据需求不同,测量方式也是会不一样的。
其实ViewGroup测量的目的是为了获取宽高,然后用于对子View的布局onLayout()(重点!)
这里给个例子,ViewGroup中有2个孩子
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
//左侧孩子布局
int width = mLeftView.getMeasuredWidth();
int height = mLeftView.getMeasuredHeight();
int left, top, right, bottom;
left = -width;
top = 0;
right = 0;
bottom = height;
mLeftView.layout(left, top, right, bottom);
//右侧孩子布局
mContentView.layout(0, 0, mContentView.getMeasuredWidth(), mContentView.getMeasuredHeight());
}
对孩子布局是调用layout(left,top,right,bottom);这个方法。对于这些left,top,right,bottom我给出一个图来看比较好懂
这里外面黑框是ViewGroup,里面红色框为子View
left:ViewGroup的left到子View的left的距离
top:ViewGroup的top到子View的top的距离
right:ViewGroup的left到子View的right的距离
bottom:ViewGroup的top到子View的bottom的距离
最后一步,也就是处理触摸事件了,也是自定义ViewGroup中含金量最高的一步了吧。
重写onInterceptTouchEvent 和 onTouchEvent这两个方法。
由于触摸事件的内容比较多,我想单独放出一篇来写