draw过程是将View绘制到屏幕上。在这个过程中 View 需要通过操作 Canvas 来实现自己 UI 效果。
ViewRootImpl
View 的 draw 起始点也是从 ViewRootImpl 开始的,ViewRootImpl 的 performDraw 方法最终会调用 drawSoftware 方法,再通过调用 DecorView 的 draw 方法来启动 draw 流程。
// ViewRootImpl 类源码
private void performTraversals() {
if (!cancelDraw) {
...
performDraw();
}
...
}
private void performDraw() {
try {
....
boolean canUseAsync = draw(fullRedrawNeeded);
....
} finally {
....
}
}
private boolean draw(boolean fullRedrawNeeded) {
....
if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) {
if (mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled()) {
...
}else {
...
if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset,
scalingRequired, dirty, surfaceInsets)) {
return false;
}
}
}
}
private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,boolean scalingRequired, Rect dirty, Rect surfaceInsets) {
final Canvas canvas;
...
try {
...
mView.draw(canvas);
...
}finally {
...
}
return true;
}
View
View 的draw方法的重点关注调用的 onDraw 和 dispatchDraw 这两个方法
/ View draw 源码
public void draw(Canvas canvas) {
....
// Step 1, draw the background, if needed
//绘制当前视图的背景
int saveCount;
drawBackground(canvas);
// skip step 2 & 5 if possible (common case)
final int viewFlags = mViewFlags;
// 获得当前视图View水平或者垂直方向是否需要绘制边框渐变效果,如果不需要绘制边框的渐变效果,就无需执行2,5了,那么就直接执行的3,4,6步骤
boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
if (!verticalEdges && !horizontalEdges) {
// Step 3, draw the content
// 绘制内容
onDraw(canvas);
// Step 4, draw the children
// 绘制子View
dispatchDraw(canvas);
drawAutofilledHighlight(canvas);
// Overlay is part of the content and draws beneath Foreground
if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().dispatchDraw(canvas);
}
// Step 6, draw decorations (foreground, scrollbars)
// 绘制装饰(前景色、滚动条)
onDrawForeground(canvas);
// Step 7, draw the default focus highlight
drawDefaultFocusHighlight(canvas);
if (isShowingLayoutBounds()) {
debugDrawFocus(canvas);
}
// we're done...
return;
}
// 下面代码用来检查是否需要保存参数canvas所描述的一块画布的堆栈状态,
// 并且创建额外的图层来绘制当前视图在滑动时的边框渐变效果
boolean drawTop = false;
boolean drawBottom = false;
boolean drawLeft = false;
boolean drawRight = false;