1.onMeasure(),onLayout(),onDraw() 构建了我们的自定义控件!
加上onTouchEvent()等重载视图的行为完成对事件的监听。
2.对于onMeasure() 主要用于测量自定义view的大小,对于
widthMeasureSpec, heightMeasureSpec这两个参数由其父容
器
ViewGroup中的layout_width,layout_height和padding以及View自身的layout_margin共同决定。
3.
widthMeasureSpec, heightMeasureSpec的作用:存储了
specMode(
MeasureSpec.getMode()获取
)
和
specSize(
MeasureSpec.getSize()获取
)。
对于
.
widthMeasureSpec, heightMeasureSpec的设置值:
childWidthMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.width);
childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);//这里是赋值的代码
4.通常ViewGroup给子控件分配的空间是不固定的,有三种可能:
- MeasureSpec.EXACTLY:父视图希望子视图的大小应该是specSize中指定的。
- MeasureSpec.AT_MOST:子视图的大小最多是specSize中指定的值,也就是说不建议子视图的大小超过specSize中给定的值。
- MeasureSpec.UNSPECIFIED:我们可以随意指定视图的大小。
private static int getRootMeasureSpec(int windowSize, int rootDimension) {
int measureSpec;
switch (rootDimension) {
case ViewGroup.LayoutParams.MATCH_PARENT:
// Window can't resize. Force root view to be windowSize.
measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.EXACTLY);
break;
case ViewGroup.LayoutParams.WRAP_CONTENT:
// Window can resize. Set max size for root view.
measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.AT_MOST);
break;
default:
// Window wants to be an exact size. Force root view to be that size.
measureSpec = MeasureSpec.makeMeasureSpec(rootDimension, MeasureSpec.EXACTLY);
break;
}
return measureSpec;
}
MATCH_PARENT对应于EXACTLY,WRAP_CONTENT对应于AT_MOST,其他情况也对应于EXACTLY
所以需要判断
rootDimension,而
rootDimension=
lp
.
width或
lp
.
height,
private void performTraversals() {
// cache mView since it is used so much below...
...
WindowManager.LayoutParams lp = mWindowAttributes;
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
mViewLayoutDirectionInitial = mView.getRawLayoutDirection();
mFallbackEventHandler.setView(view);
mWindowAttributes.copyFrom(attrs);
5.影响specSize height的因素为:父视图的layout_height和paddingTop以及自身的layout_marginTop相似的可以知道
specSize width,
6.调用setMeasureDimension()函数最终完成对view的大小的设置。