#自定义控件
控件都是View的子类
##控件的分类
###1.容器类ViewGroup及其子类
存放和摆放子控件
###2.非容器类
有具体的功能
##控件的四大流程
1. 初始化 ---> 构造函数 (创建控件对象)
2. 测量 ----> 测量和确定控件的宽和高
3. 布局排版 ---> 如果控件是一个容器,布局就是管理子控件怎么摆放。注意:只有ViewGroup需要重写这个方法
4. 绘制 ----> 画出自已
##流程对应的四个方法如下;
###1. 初始化 ---> 构造函数 (创建控件对象) ##
a.在初始化时可以拿到自定义的属性值
b.在初始化时可以拿到要绘制的图片资源
c.在初始化时可以拿到要添加的xml控件资源
public ToggleButton(Context context, AttributeSet attrs) {
super(context, attrs);
//属性资源
//obtainStyledAttributes( AttributeSet set, int[] attrs)
//图片资源
//Bitmap decodeResource(Resources res, int id)
//加载资源
//View.inflate(context, R.layout.rate, this);
}
###2.测量 ----> 测量和确定控件的宽和高 ##
测量控件有三种模式
1.MeasureSpec.AT_MOST 致多模式 wrap_content时对应
2.MeasureSpec.EXACTLY 精确模式 match_parent和具体dp时对应
3.MeasureSpec.UNSPECIFIED 未指定模式 (一般系统调用)
需要重写一个方法来改写父类的getDefaultSize(size, measureSpec)方法,此方法默认wrap_content和match_parent一样
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//heightMeasureSpec widthMeasureSpec 封装布局文件中指定布局的高和宽的信息
//32位 存了两种信息 00 前两位: 表示模式 总共有三种模式
//000000 00000000 00000000 00000000 后面30位 :表示就是大小(size)
//wrap时得到宽如下:高类似
// MeasureSpec为解析模式的工具类
int widthMode = MeasureSpec.getMode(widthMeasureSpec); //获取模式
int widthSize = MeasureSpec.getSize(widthMeasureSpec);//获取大小
switch (widthMode) {
case MeasureSpec.AT_MOST: //致多模式 ===》 当在布局文件中写wrap_content的时候模式,并且size 和 父控件一样大.
Log.i("test", "AT_MOST SIZE:" + widthSize);
widthSize = dashboard.getWidth();
break;
case MeasureSpec.EXACTLY: //精确模式 ===》 当在布局文件中写精确的值和match_parent的时候的模式,并且size如果是写精确的值就是精确的值,如果是match_parent和父控件一样大
Log.i("test", "EXACTLY SIZE:" + widthSize);
break;
case MeasureSpec.UNSPECIFIED: //未指定模式
Log.i("test", "UNSPECIFIED SIZE:" + widthSize);
widthSize = dashboard.getWidth();
break;
default:
break;
}
setMeasuredDimension(widthSize, heightSize);
//重写得到wrap_content时控件的宽高,可以改写系统的如下方法
//getDefaultSize(size, measureSpec)-系统设置控件宽高时调用
}
###3. 布局排版 ---> 如果控件是一个容器,布局就是管理子控件怎么摆放。
//继承ViewGroup时重写这个方法摆放子控件
//此方法中的参数为当前空件左上点和右下点的坐标
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
//子控件.layout(l, t, r, b );对子控件进行摆放,只需确认左上点和右下点
super.onLayout(changed, left, top, right, bottom);
}
###4. 绘制 ----> 画出自已
//将图片绘制在对应的地方,需要时调用invalidate();重新绘制改变图片的位置
//一般继承view时使用
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//将图片画在所需地方,只用确定左上点的坐标
canvas.drawBitmap(bg, 0, 0, null);
canvas.drawBitmap(button, left, 0, null);
}
##对外提供接口
让使用控件的人重写接口中的方法
在控件不同的状态调用不同的方法
##对外提供公共的方法
方便使用者调用设置自己所需的值
在控件不同的状态调用不同的方法完成后,需要调用的方法
控件都是View的子类
##控件的分类
###1.容器类ViewGroup及其子类
存放和摆放子控件
###2.非容器类
有具体的功能
##控件的四大流程
1. 初始化 ---> 构造函数 (创建控件对象)
2. 测量 ----> 测量和确定控件的宽和高
3. 布局排版 ---> 如果控件是一个容器,布局就是管理子控件怎么摆放。注意:只有ViewGroup需要重写这个方法
4. 绘制 ----> 画出自已
##流程对应的四个方法如下;
###1. 初始化 ---> 构造函数 (创建控件对象) ##
a.在初始化时可以拿到自定义的属性值
b.在初始化时可以拿到要绘制的图片资源
c.在初始化时可以拿到要添加的xml控件资源
public ToggleButton(Context context, AttributeSet attrs) {
super(context, attrs);
//属性资源
//obtainStyledAttributes( AttributeSet set, int[] attrs)
//图片资源
//Bitmap decodeResource(Resources res, int id)
//加载资源
//View.inflate(context, R.layout.rate, this);
}
###2.测量 ----> 测量和确定控件的宽和高 ##
测量控件有三种模式
1.MeasureSpec.AT_MOST 致多模式 wrap_content时对应
2.MeasureSpec.EXACTLY 精确模式 match_parent和具体dp时对应
3.MeasureSpec.UNSPECIFIED 未指定模式 (一般系统调用)
需要重写一个方法来改写父类的getDefaultSize(size, measureSpec)方法,此方法默认wrap_content和match_parent一样
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//heightMeasureSpec widthMeasureSpec 封装布局文件中指定布局的高和宽的信息
//32位 存了两种信息 00 前两位: 表示模式 总共有三种模式
//000000 00000000 00000000 00000000 后面30位 :表示就是大小(size)
//wrap时得到宽如下:高类似
// MeasureSpec为解析模式的工具类
int widthMode = MeasureSpec.getMode(widthMeasureSpec); //获取模式
int widthSize = MeasureSpec.getSize(widthMeasureSpec);//获取大小
switch (widthMode) {
case MeasureSpec.AT_MOST: //致多模式 ===》 当在布局文件中写wrap_content的时候模式,并且size 和 父控件一样大.
Log.i("test", "AT_MOST SIZE:" + widthSize);
widthSize = dashboard.getWidth();
break;
case MeasureSpec.EXACTLY: //精确模式 ===》 当在布局文件中写精确的值和match_parent的时候的模式,并且size如果是写精确的值就是精确的值,如果是match_parent和父控件一样大
Log.i("test", "EXACTLY SIZE:" + widthSize);
break;
case MeasureSpec.UNSPECIFIED: //未指定模式
Log.i("test", "UNSPECIFIED SIZE:" + widthSize);
widthSize = dashboard.getWidth();
break;
default:
break;
}
setMeasuredDimension(widthSize, heightSize);
//重写得到wrap_content时控件的宽高,可以改写系统的如下方法
//getDefaultSize(size, measureSpec)-系统设置控件宽高时调用
}
###3. 布局排版 ---> 如果控件是一个容器,布局就是管理子控件怎么摆放。
//继承ViewGroup时重写这个方法摆放子控件
//此方法中的参数为当前空件左上点和右下点的坐标
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
//子控件.layout(l, t, r, b );对子控件进行摆放,只需确认左上点和右下点
super.onLayout(changed, left, top, right, bottom);
}
###4. 绘制 ----> 画出自已
//将图片绘制在对应的地方,需要时调用invalidate();重新绘制改变图片的位置
//一般继承view时使用
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//将图片画在所需地方,只用确定左上点的坐标
canvas.drawBitmap(bg, 0, 0, null);
canvas.drawBitmap(button, left, 0, null);
}
##对外提供接口
让使用控件的人重写接口中的方法
在控件不同的状态调用不同的方法
##对外提供公共的方法
方便使用者调用设置自己所需的值
在控件不同的状态调用不同的方法完成后,需要调用的方法