View中:
- Draw the background 绘制背景
- If necessary, save the canvas’ layers to prepare for fading. 如有必要,颜色渐变淡之前保存画布层(即锁定原有的画布内容)
- Draw view’s content. 绘制view的内容
- Draw children. 绘制子view
- If necessary,draw the fading edges and restore layers. 如有必要,绘制颜色渐变淡的边框,并恢复画布(即画布改变的内容附加到原有内容上)
- Draw decorations (scrollbars for instance). 绘制装饰,比如滚动条
public void draw(Canvas canvas){
...
if(!dirtyOpaque){
drawBackground(canvas);//背景绘制
}
// skip step 2 & 5 if possible (common case) 通常情况跳过第2和第5步
...
if(!dirtyQpaque) onDraw(canvas); // 调用onDraw
dispatchDraw(canvas); // 绘制子view
onDrawScrollBars(canvas); // 绘制滚动条
...
}
protected void dispatchDraw(Canvas canvas){// 空实现}
protected void onDraw(Canvas canvas){// 空实现}
ViewGroup中:
protected void dispatchDraw(Canvas canvas){
...
drawChild(...); // 绘制子View
...
}
protected boolean drawChild(Canvas canvas, View child, long drawingTime){
return child.draw(canvas, this, drawingTime);
}
说明:
-
自定义一个View时,重写onDraw。
调用view.invalidate(), 会触发onDraw和computeScroll(). 前提是该View被附加在当前窗口
view.postInvalidate();//是在非UI线程上调用的 -
自定义一个ViewGroup,重写onDraw。
onDraw可能不会被调用,原因是需要先设置一个背景(颜色或图)
表示这个group有东西需要绘制了,才会触发draw,之后是onDraw。
因此,一般直接重写dispatchDraw来绘制viewGroup -
自定义一个ViewGroup
dispatchDraw会调用drawChild。