View的绘制流程

View是如何被添加到品目窗口上

  1. 创建顶层布局容器DecorView
  2. 在顶层布局中加载基础布局ViewGroup
  3. 将ContentView添加到基础布局中的FrameLayout中

View的绘制流程

绘制入口

ActivityThread.handleResumeActivity ->
WindowManagerImpl.addView(dercorView, layoutParams)->
WindowManagerGlobal.addView()

绘制的类及方法

ViewRootImpl.setView(decorView, layoutParams, parentView)->
ViewRootImpl.requestLayout()->scheduleTraversals()->doTraversal()->
performTraversals()

绘制的三大步骤

测量:ViewRootImpl.performMeasure
布局:ViewRootImpl.performLayout
绘制:ViewRootImpl.performDraw

View的绘制

MeasureSpec由SpecMode(前两位) + SpecSize(后三十位) 组成的32位int值

int MODE_SHIFT = 00000000000000000000000000000000;
// 父容器不对View做任何限制,系统内部使用
UNSPECIFIED = 0 << MODE_SHIFT; // 0
// match_parent
EXACTLY = 1 << MODE_SHIFT; // 01000000000000000000000000000000
// wrap_conent
AT_MOST = 2 << MODE_SHIFT; //10000000000000000000000000000000
View的测量-确定DecorView的MeasureSpec

DecorView的MeasureSpec由窗口大小和自身LayoutParams决定,遵守如下规则:

  • LayoutParams.MATCH_PARENT:精确模式,窗口大小
  • LayoutParams.WRAP_CONTENT:最大模式,最大为窗口大小
  • 固定大小:精确模式,大小为LayoutParams的大小

View的MeasureSpec由父容器的MeasureSpec和自身LayoutParams决定


View的绘制流程_第1张图片
image.png
ViewGroup measure流程:

onMeasure(测量子控件的宽高) --> setMeasureDimension --> setMeasureDimensionRaw(保存自己的宽高)

View measure流程:

onMeasure --> setMeasureDimension --> setMeasureDimensionRaw(保存自己的宽高)

View的布局
  • 调用view.layout确定自身的位置,即确定mLeft、mTop、mRight、mBottom的值。
  • 如果是ViewGroup类型,需要调用onLayout确定子View的位置。
View的绘制
  • 绘制背景drawBackground(canvas)
  • 绘制自己onDraw(canvas)
  • 绘制子view dispatchDraw(canvas)
  • 绘制前景,滚动条等装饰onDrawForeground(canvas)

你可能感兴趣的:(View的绘制流程)