View工作原理 -- 工作过程 -- draw

draw过程的作用是将View绘制到屏幕上面。View的绘制过程遵循如下几步:

  1. 绘制背景 background.draw(canvas)
  2. 绘制自己 (onDraw)
  3. 绘制children (dispatchDraw)
  4. 绘制装饰 (onDrawScrollBars)

View绘制过程的传递是通过dispatchDraw来实现的,dispatchDraw会遍历调用所有子元素的draw方法,如此draw事件就一层层地传递了下去。

View有一个特殊的方法setWillNotDraw,如果一个View不需要绘制任何内容,那么设置这个标记位为true后,系统会进行相应的优化。默认情况下,View没有启用这个优化标记位,但是ViewGroup会默认启用这个优化标记位。
这个标记位的意义是:当我们的自定义控件继承于ViewGroup并且自身不具备绘制功能时,就可以开启这个标记位从而便于系统进行后续的优化。当然,当明确知道一个ViewGroup需要通过onDraw来绘制内容时,我们需要显示地关闭WILL_NOT_DRAW这个标记位。

源码分析自定义ViewGroup onDraw方法无效
自定义View继承于ViewGroup,如果不设置背景并且不调用setWillNotDraw(false)方法,那么内容就不会绘制出来,仅当设置了背景或者调用了setWillNotDraw(false)方法后,内容才能绘制出来。

Android View 深度分析requestLayout、invalidate与postInvalidate
子View调用requestLayout方法,会标记当前View及父容器,同时逐层向上提交,直到ViewRootImpl处理该事件,ViewRootImpl会对每一个含有标记位的View及其子View都会进行测量、布局、绘制。

子View调用invalidate方法,会为该View添加一个标记位,同时不断向父容器请求刷新,父容器通过计算得出自身需要重绘的区域,直到传递到ViewRootImpl中,最终触发performTraversals方法,进行View树重绘流程(只绘制需要重绘的视图)。

postInvalidate方法与invalidate方法的作用是一样的,都是使View树重绘,postInvalidate可以在非UI线程中调用,invalidate则是在UI线程中调用。

你可能感兴趣的:(View工作原理 -- 工作过程 -- draw)