自定义view探索
构造方法
一般来说有四种构造方法,传入的参数不同。但出入四个参数的在API 21才加入,暂不考虑。传入style的后续再说,重点注意两个。
//一般在直接New一个View的时候调用。
public void MyView(Context context) {}
//一般在layout文件中使用的时候会调用,关于它的所有属性(包括自定义属性)都会包含在attrs中传递进来。
public void MyView(Context context, AttributeSet attrs) {}
eg.
传入单个参数的构造方法:
MyView view = new Myview(this);
在调用传入两个参数构造方法时,需要将布局文件在layout目录中写好,格式为包名+view名
<com.zbd.Demo.MyView
android:height = "match_parent"
android:width = "match_parent"/>
测量view大小
view的大小不仅和自身有关,也和父控件有关,因此测量view的实际大小非常重要。
测量view大小常用的是onMeasure()函数,可以取出其高和宽的相关数据。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthsize MeasureSpec.getSize(widthMeasureSpec);
//取出宽度的确切数值
int widthmode MeasureSpec.getMode(widthMeasureSpec);
//取出宽度的测量模式
int heightsize MeasureSpec.getSize(heightMeasureSpec);
//取出高度的确切数值
int heightmode MeasureSpec.getMode(heightMeasureSpec);
//取出高度的测量模式
}
从上面可以看出 onMeasure 函数中有 widthMeasureSpec 和 heightMeasureSpec 这两个 int 类型的参数, 毫无疑问他们是和宽高相关的, 但它们其实不是宽和高, 而是由宽、高和各自方向上对应的测量模式来合成的一个值。
注意:
如果对View的宽高进行修改了,不要调用 super.onMeasure( widthMeasureSpec, heightMeasureSpec); 要调用 setMeasuredDimension( widthsize, heightsize); 这个函数。
确定view的大小
此函数在view大小发生变化时调用
方法:onSizeChanged
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
有四个参数:
w:宽度
h:高度
oldw:上一次宽度
oldh:上一次高度
重点关注w,h,这两个是view的最终大小
确定子view布局
确定布局的函数是onLayout,它用于确定子View的位置,在自定义ViewGroup中会用到,他调用的是子View的layout函数。
在自定义ViewGroup中,onLayout一般是循环取出子View,然后经过计算得出各个子View位置的坐标值,然后用以下函数设置子View位置。
child.layout(l, t, r, b);
l:View左侧距父View左侧的距离 获取方法:getLeft();
t:View顶部距父View顶部的距离 获取方法:getTop();
r:View右侧距父View左侧的距离 获取方法:getRight();
b:View底部距父View顶部的距离 获取方法:getBottom();
绘制内容
通过onDraw实现(重点待补充)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
对外提供监听和回调
重点内容
自定义view启动顺序
1.构造函数 进行初始化操作
2.onMeasure() 测量view尺寸大小
3.onSizeChanged() 确定view大小
4.onLayout() 确定子View布局属性(仅在包含子view时有效)
5.onDraw() 绘制view实际内容
6.提供接口 控制view或提供某些监听