首先明确View是如何被添加到屏幕窗口上的
1创建顶层布局容器 DecorView
2在顶层布局中加载基础布局ViewGroup
3.ContentView添加到基础布局中的FrameLayout中
View的绘制流程 (DecorView添加到窗口Window的过程)
AndroidThread(HandlerResumeActivity())->WindowManagerImpl(addView())->
WindowManagerGlobal(addView())->ViewRootImpl(addView())->
ViewRootImpl(requestLayout())->ViewRootImpl(scheduleTraversals())->
ViewRootImpl(doTraversal())->ViewRootImpl(performTraversals)
绘制三大步骤
在performTraversals()方法中
ViewRootImpl.performMeasure
ViewRootImpl.performLayout
ViewRootImpl.performDraw
View= 模式+ 尺寸->measureSpec 32位int值
mode_mask:1100000 00000 00000 00000 00000 00000
~mode_mask:00 11111 11111 11111 11111 11111 11111
unspecidied=0 <<00000......//父容器不对view做任何限制
exactly =1 << 01000000...//父容器检测出view的大小,view的大小就是specSize layoutparam match_parent固定大小
at_most=2<<1000000....//父容器置顶一个可用大小,View的大小不能超过这个值 layoutParams wrao_content
DecorView的MeasureSpec 由窗口大小和自身LayoutParams决定,
LayoutParam.Mactch_parent:精确模式,窗口大小
LayoutParam.Wrap_content:最大模式,最大为窗口大小
固定大小:精确模式,大小为LayoutParams的大小
ViewGroup measure->onMeasure(测量子控件的宽高)-->setMeasureDimension-->setMeasureDimensionRaw(保存自己的宽高)
View measure ->onMeasure ->setMeasureDimension-->setMeasureDimensionRaw(保存自己宽高)
layout:
ViewGroup 调用layout来确定自己的位置左上右下 ,然后, 需要调用onLayout来确定子View的布局
View 只需要调用layout方法确定左向右下就行
draw
View
绘制背景drawBackground(canvas)
绘制自己onDraw(canvas)
绘制前景,滚动条等装饰 onDrawForeground(canvas)
ViewGroup
绘制背景drawBackground(canvas)
绘制自己onDraw(canvas)
绘制子View dispatchDraw(canvas)
绘制前景,滚动条等装饰 onDrawForeground(canvas)