以前我们布局界面都是利用五大布局,但有时,对于一些布局往往需要多层嵌套,这时候往往自定义的ViewGroup能够更容易的来布好局,今天我们来学习一下如何创建自定义的ViewGroup吧^^。
ViewGroup的职能为:给childView计算出建议的宽和高和测量模式
;决定childView的位置;为什么只是建议的宽和高,而不是直接确定呢,别忘了childView宽和高可以设置为wrap_content,这样只有childView才能计算出自己的宽和高。
一、使用方法:
1.自定义viewGroup必须继承ViewGroup类
2.仍旧重写两个构造器:
public MyViewGroup(Context context){}
public MyViewGroup(Context context, AttributeSet attrs){}//在这个构造器中才能获得xml布局中的属性设置。
3.最重要的两个方法:
onMessure():测量自己的宽高,并且设置child的宽高(通过ViewGroup的measureChildren方法为其所有的孩子设置宽和高)。
获取该ViewGroup父容器为其设置的计算模式和尺寸,大多情况下,只要不是wrap_content,父容器都能正确的计算其尺寸。所以我们自己需要计算如果设置为wrap_content时的宽和高,如何计算呢?那就是通过其childView的宽和高来进行计算。
onLayout():对其所有childView进行定位
二、范例:
功能:实现自定义一个viewGroup:管理四个view分别位于:
左上角,右上角,左下角,右下角
总代码:
public class MyViewGroup extends ViewGroup {//1.继承ViewGroup
private int width;
private int height;
public MyViewGroup(Context context) {
super(context);
}
public MyViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//2.测量,先测量child
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);//1)得到viewgroup的宽高
height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
measureChildren(width, height);//2)使用系统自带的测量方法测量子view宽高
}
@Override//这里的l、t,r,b分别是指viewgroup的left,top,right,和bottom
protected void onLayout(boolean changed, int l, int t, int r, int b) {
View child1 = getChildAt(0);//3.得到子view
if (child1 != null) {
child1.layout(0, 0, child1.getMeasuredWidth(), child1.getMeasuredHeight());
}
View child2 = getChildAt(1);
if (child2 != null) {
child2.layout(r - child2.getMeasuredWidth(), 0, r, child2.getMeasuredHeight());
}
View child3 = getChildAt(2);
if (child3 != null) {
child3.layout(0, b - child3.getMeasuredHeight(), child3.getMeasuredWidth(), b);
View child4 = getChildAt(3);
if (child4 != null) {
child4.layout(r - child4.getMeasuredWidth(), b - child4.getMeasuredHeight(), r, b);
}
}
}
}
三、getHeight与getMessureHeight区别:
实际上在当屏幕可以包裹内容的时候,他们的值相等,
只有当view超出屏幕后,才能看出他们的区别:
getMeasuredHeight()是实际View的大小,与屏幕无关,
而getHeight的大小此时则是屏幕的大小。
当超出屏幕后,getMeasuredHeight()等于getHeight()加上屏幕之外没有显示的大小。