Android View 全解析(一) -- 窗口管理系统
1.window
WindowManeger ViewRoot View Window
Dialog、Activity 以及 Toast 都是展示在 Window 上面的。 PhoneWindow
WindowManangerService Session
ViewRoot---> handler 通知view绘制,通知WindowManager,把view加到window上。
PhoneWindow -》DecorView
当 Choreographer 接收到 VSYNC 信号后,ViewRootImpl 调用 scheduleTraversals 方法,通知 View 进行相应的渲染,其后 ViewRootImpl 将 View 添加或更新到 Window 上去。
2.onMeasuer()
onMeasure
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec),getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec));}
measureChildWithMargins
MarginLayoutParams,大部分的容器 View (LinearLayout、FrameLayout等
measureChild这个方法与前面这个是相对的,不同之处在于只考虑自身的 padding,不考虑 margin
measureChildren对所有可见 view 调用 measureChild 方法。
getChildMeasureSpec
分别有三个参数,当前view的measureSpec, 当前view 的 padding(或者加上margin), 当前 view 期望的大小(不一定会实现)
1.如果子view layoutParams是dip(Size),子 view MeasureSpec肯定是 EXACTLY+SIZE。
下面都是排除第一条规则前提:
2.如果是父view 是 UNSPECIFIED , 子view Measure 肯定是UNSPECIFIED+0
3.如果是父 view是AT_MOST +SIZE ,子view Measure 肯定是AT_MOST +SIZE(随父)
4.如果是父 view是EXACTLY+SIZE ,子view Measures同步 子 LayoutParams(随子)
3.onLayout()
getTop view左上角与父view之间的距离
getBottom子View右下角距父View顶部的距离
getLeft子View左上角距父View左侧的距离
getRight子View右下角距父View左侧的距离
MotionEvent, event 中的 getX 和 getY , 分别是相对于父 View 而言的
相对于屏幕左上角的坐标可以用 getRawX 和 getRawY
onLayout(booleanchanged,intleft,inttop,intright,intbottom)
// 可使用的父 view 的左边界范围,这里的边界是综合考虑了 foreground 和 padding的finalintparentLeft=getPaddingLeftWithForeground();// 右边界。right 和 left 分别是指左右两边的 X 坐标// 两者相减,再减去右边的 padding 可以得到父 view 的右边界范围。finalintparentRight=right-left-getPaddingRightWithForeground();// 与上面类似,就不重复写了finalintparentTop=getPaddingTopWithForeground();finalintparentBottom=bottom-top-getPaddingBottomWithForeground();
1.方法传入的left,top, right, bottom,的值是该ViewGroup 相对他的父亲getTop,getBottom,
getLeft,getRight的值,
2.在该ViewGroup 当中测量子View的位置时,调用
// 最重要的地方,将计算得出的四个位置作为参数,设置进去。child.layout(childLeft,childTop,childLeft+width,childTop+height)
传入的值同样一样,利用parentLeft,parentRight,parentTop,parentBottom,
// width 和 height 分别是 Measure 过后的 宽和高finalintwidth=child.getMeasuredWidth();finalintheight=child.getMeasuredHeight();
一起计算对应相对他的父亲getTop,getBottom,
getLeft,getRight的值。
4.ondraw()
PaintMatrix matrix, Paint paint,canvas
canvas.drawRect(200,200,400,400,paint);
canvas.drawBitmap(bgBitmap,newMatrix(),newPaint());
path 关于直线的操作,主要是两个 moveTo 和 lineTo,moveTo 移动下一次绘制操作开始的起点,例如 moveTo(20,20),那么下一次操作就从(20,20) 这里开始。而 lineTo 就更加直接一点,直接在设定的起点(默认为(0,0))开始,到指定的结束为止绘制一条直线。
贝塞尔曲线
这时候,链接 DE 两点,在这条链接线上在找一点 F,使得 DF/DE = AD/AB = BE/BC