View是如何被添加到屏幕窗口上
创建顶层布局容器 DecorView
在顶层布局中加载基础布局 ViewGroup
将 ContentView 添加到基础布局中的 FrameLayout 中
简答:首先系统会创建一个顶层布局容器叫 DecorView,DecorView 是一个 ViewGroup 容器,继承 FrameLayout,是 PhoneWindow 对象持有的一个实例,它是所有应用程序的顶层 View。在系统内部进行初始化,当 DecorView 初始化完成后,系统会根据应用程序的主题特性去加载一个基础容器,例如说:NoActionBar 或者 DarkActionBar,不同的主题加载的基础容器也不一样,但是这些基础容器都有一个共同的地方就是
View 的绘制流程
1、绘制入口
ActivityThread.handleResumeActivity
WindowManagerImpl.addView(decorView, layoutParams)
WindowManagerGlobal.addView()
2、绘制的类及方法
ViewRootImpl.setView(decorView, layoutParms, parentView)
ViewRootImpl.requestLayout() —> scheduleTraversals() —> doTraversal()
performTraversals()
3、绘制三大步骤
测量:ViewRootImpl.performMeasure
view.measure —> view.onMeasure —> view.setMeasuredDimension —> setMesasuredDimensionRaw
布局:ViewRootImpl.performLayout
view.layout —> view.onLayout
绘制:ViewRootImpl.performDraw
ViewRootImpl.draw(fullRedrawNeeded) —> ViewRootImpl.drawSoftware —> view.draw(Canvas)
View 的测量-确定 DecorView 的 MeasureSpec
- DecorView 的 MeasureSpec 由窗口大小和自身 LayoutParams 决定,遵守规则如下:
- 1、LayoutParams.MATCH_PARENT:精确模式,窗口大小
- 2、LayoutParams.WRAP_CONTENT:最大模式,最大为窗口大小
- 3、固定大小:精确模式,大小为 LayoutParams 的大小
- View 的测量-确定 View 的 MeasureSpec
- View 的 MesaureSpec 由父容器的 MeasureSpec 和自身 LayoutParams 决定
View 的布局
- 调用 view.layout 确定自身的位置,即确定 mLeft,mTop,mRight,mBottom 的值。
- 如果是 ViewGroup 类型,需要调用 onLayout 确定子 View 的位置。
View 的绘制
- 绘制背景 drawBackground(canvas)
- 绘制自己 onDraw(canvas)
- 绘制子 View dispatchDraw(canvas)
- 绘制前景,滚动条等装饰 onDrawForeground(canvas)