自定义view 对象显示的屏幕上,有几个重要步骤:
1、构造方法 创建 对象。(就是那三个构造方法)
第二个是创建布局文件调用的构造函数
2、测量view的大小。 设置自己显示在屏幕上的宽高, onMeasure(int,int)
- setMeasuredDimension(backgroundBitmap.getWidth(),backgroundBitmap.getHeight());如果知道了自定义控件的大小,那么就这样设置当前view的大小,用这个需要super去掉,继承view的话这样写
- 但是如果需要重新测量或者动态改变自定义控件大小那就需要根据自己需求重写规则makeMeasureSpec,简单说就是规则改变了就需要重写规则,再通过measure方法测量,重写测完的宽高这样写getMeasuredWidth()。继承viewgroup的话这样写,因为viewGroup 有责任计算每个孩子的大小
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int size = MeasureSpec.getSize(widthMeasureSpec); int mode = MeasureSpec.getMode(widthMeasureSpec); for (int i = 0; i < getChildCount(); i++) { View v = getChildAt(i); v.measure(widthMeasureSpec, heightMeasureSpec); // v.getMeasuredWidth() // 得到测量的大小 }
3、确定view的位置 ,view自身有一些建议权,决定权在 父view手中。 设置自己显示在屏幕上的位置(只有在自定义ViewGroup中才用到)
- 参数说明:参数changed表示view有新的尺寸或位置;参数l表示相对于父view的Left位置;参数t表示相对于父view的Top位置;参数r表示相对于父view的Right位置;参数b表示相对于父view的Bottom位置。左上右下
- 调用场景:在view给其孩子设置尺寸和位置时被调用。子view,包括孩子在内,必须重写onLayout(boolean, int, int, int, int)方法,并且调用各自的layout(int, int, int, int)方法。
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
4、绘制 view 的内容 。 onDraw(Canvas)
控制显示在屏幕上的样子(自定义viewgroup时不需要这个)
绘制 背景
/*
* backgroundBitmap 要绘制的图片
* left 图片的左边届
* top 图片的上边届
* paint 绘制图片要使用的画笔
*/
canvas.drawBitmap(backgroundBitmap, 0, 0, paint);
View和ViewGroup的区别
- 他们都需要进行测量操作
- ViewGroup主要是控制子view如何摆放,所以必须实现onLayout。
- View没有子view,所以不需要onLayout方法,但是必须实现onDraw
- 在自定义ViewGroup中一般不需要去实现onMeasure, 我们去实现系统已有的ViewGroup,比如FrameLayout, 它会帮我们区实现onMeasure方法
getHeight()和getMeasuredHeight()的区别:
- getMeasuredHeight(): 控件实际的大小
获取测量完的高度,只要在onMeasure方法执行完,就可以用它获取到宽高,在自定义控件内部多使用这个使用view.measure(0,0)方法可以主动通知系统去测量,然后就可以直接使用它获取宽高
- getHeight():控件显示的大小,必须在onLayout方法执行完后,才能获得宽高
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
headerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int headerViewHeight = headerView.getHeight();
//直接可以获取宽高
}
});
这俩个一般情况是一样的,但是在viewgroup里getWidth是父类给子view分配的空间:右边-左边
自定义view常用方法
附件列表
时间: 2024-11-16 21:16:53