需求:在ViewGroup中显示一个TextView
1、继承ViewGroup
必须要实现其构造方法和一个onLayout方法
构造函数的处理:
public CusViewGroup(Context context) {
this(context, null);
}
public CusViewGroup(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CusViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
注意构造函数中的this。自定义ViewGroup也能够有自己的属性,对于属性的操作和自定义View一致。(在Style中添加自定义属性,在构造函数中获取到layout中设置的自定义属性的值)
onLayout():
疑问:为什么必须要重写onLayout方法?
–自定义ViewGroup 相当于是一个容器,里面能够放置很多View,这些View的位置由onLayout来确定。必须指定位置,才能显示到容器的对应位置上。
疑问:onLayout的几个参数是什么意思
l、t、r、b 是自定义ViewGroup父控件中设置的Padding 值。
2、自定义ViewGroup的执行过程
构造函数—–获取自定义属性
onMeasure—控件宽、高以及measure子控件
onLayout —–控件的位置,子View的位置
onDraw —— 画画咯
onMeasure:
自定义ViewGroup onMeasure代码
/**
* 确定ViewGroup的宽高
*
* @param widthMeasureSpec 宽参数
* @param heightMeasureSpec 高参数
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//ViewGroup主要是一个容器,当ViewGroup的宽高是确切的值的时候,控件的宽高就是它本身设置的值
//主要是考虑ViewGroup Wrap_content的时,需要计算控件的宽高,控件的宽高根据子View的布局来计算
int width;
int height;
int mWidthMeasureMode = MeasureSpec.getMode(widthMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);//初始化所有子View的宽高
if (mWidthMeasureMode == MeasureSpec.AT_MOST) {
//Wrap_content的情况
//测量子View的宽 怎么测量子View的宽
//由于这里只有一个控件,暂时从这个一个控件开始学习
View childView = getChildAt(0);//获取到这个控件
width = childView.getMeasuredWidth();
} else {
width = MeasureSpec.getSize(widthMeasureSpec);
}
int mHeightMeasureMode = MeasureSpec.getMode(heightMeasureSpec);
if (mHeightMeasureMode == MeasureSpec.AT_MOST) {
View childView = getChildAt(0);
height = childView.getMeasuredHeight();
} else {
height = MeasureSpec.getSize(heightMeasureSpec);
}
setMeasuredDimension(width, height);
}
测试布局文件:
<com.tjstudy.cusviewgroupdemo.customerview