自定义View 包含什么?
布局: onlayout onmeausre/ Layout:viewGroup
显示: onDraw ( canvas、 paint 、matrix、 clip、 rect 、animation 、path、line text绘制等)
交互: onTouchEvent
view四个构造函数的区别
MeasureSpec
MeasureSpec是32位int类型的值,是View中的内部类
高两位表示mode,低30位表示size。
MeasureSpec值是view的父view给的,是measure(onMeasure)方法的参数。
通常,viewGroup中的measure为如下逻辑:先度量孩子,根据孩子的大小再确定自己的大小。
(度量时先度量自己还是先度量孩子?答:都可以,看不同的算法,一般是先孩子再自己)
//度量孩子
childView.measure(widthMeasureSpec,heightMeasureSpec);
//度量孩子后,获取孩子的宽高
childView.getMesuredHeight()
childView.getMesuredWidth()
//度量完自己,调用如下
setMeasuredDimension(width,heighy);
度量时,LayoutParams的作用
LayoutParams是View用来告诉它的父控件如何放置自己的,是ViewGroup类里的一个静态内部类,表示view想要的宽高、padding、margin等。
常见的度量相关方法
MeasureSpec.getSize(widthMeasureSpec)
//onMeasure中获取父布局给的宽高
int selfWidth = MeasureSpec.getSize(widthMeasureSpec); //解析的父view给我的宽度
int selfHeight = MeasureSpec.getSize(heightMeasureSpec); //解析的父view给我的高度
getChildMeasureSpec
LayoutParams childLP = childView.getLayoutParams();
//将layoutParams转变成为 measureSpec
int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, paddingLeft + paddingRight, childLP.width);
int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, paddingTop + paddingBottom, childLP.height);
//度量childView
childView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
//获取子view的度量宽高
int childMesauredWidth = childView.getMeasuredWidth();
int childMeasuredHeight = childView.getMeasuredHeight();
/**
* Does the hard part of measureChildren: figuring out the MeasureSpec to
* pass to a particular child. This method figures out the right MeasureSpec
* for one dimension (height or width) of one child view.
*
* The goal is to combine information from our MeasureSpec with the
* LayoutParams of the child to get the best possible results. For example,
* if the this view knows its size (because its MeasureSpec has a mode of
* EXACTLY), and the child has indicated in its LayoutParams that it wants
* to be the same size as the parent, the parent should ask the child to
* layout given an exact size.
*
* @param spec The requirements for this view
* @param padding The padding of this view for the current dimension and
* margins, if applicable
* @param childDimension How big the child wants to be in the current
* dimension
* @return a MeasureSpec integer for the child
*/
public static int getChildMeasureSpec(int spec, int padding, int childDimension)
常用的对孩子进行测量的方法是getChildMeasureSpec(),其中spec和padding是父亲的,childDimension是孩子想要的长度。
自定义viewGroup时怎么度量
自定义View
流程如下:
onMeasure是测量view的大小尺寸
onLayout是给子View布局
onDraw是绘制实际的内容
自定义View主要是实现 onMeasure + onDraw
自定义ViewGroup主要是实现onMeasure + onLayout