View
public void draw(Canvas canvas) {
//...
/*
* Draw traversal performs several drawing steps which must be executed
* in the appropriate order:
*
* 1. Draw the background
* 2. If necessary, save the canvas' layers to prepare for fading
* 3. Draw view's content
* 4. Draw children
* 5. If necessary, draw the fading edges and restore layers
* 6. Draw decorations (scrollbars for instance)
*/
// Step 1, draw the background, if needed
int saveCount;
if (!dirtyOpaque) {
drawBackground(canvas);
}
// skip step 2 & 5 if possible (common case)
final int viewFlags = mViewFlags;
boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
if (!verticalEdges && !horizontalEdges) {
// Step 3, draw the content
if (!dirtyOpaque) onDraw(canvas);
// Step 4, draw the children
dispatchDraw(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);
// we're done...
return;
}
/*
* Here we do the full fledged routine...
* (this is an uncommon case where speed matters less,
* this is why we repeat some of the tests that have been
* done above)
*/
/
// Step 2, save the canvas' layers
//...
// Step 3, draw the content
if (!dirtyOpaque) onDraw(canvas);
// Step 4, draw the children
dispatchDraw(canvas);
// Step 5, draw the fade effect and restore layers
//...
// 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);
}
protected void onDraw(Canvas canvas) {}
protected void dispatchDraw(Canvas canvas) {}
流程:
- 繪制背景
- save the canvas' layers 準備用于繪制View在滑動時的邊框漸變效果
- 繪制View的內(nèi)容帐姻,onDraw()奶段,是個空方法
- 調(diào)用dispatchDraw()剥纷,View類里是個空方法,ViewGroup類里會遍歷所有child晦鞋,調(diào)用child.draw()
- 繪制View在滑動時的邊框漸變效果
- 繪制View的滾動條(可以看出所有的View都有滾動條)
總結(jié):
自定義View基本只需重寫onDraw()方法悠垛,其他5個步驟無需管理。關(guān)于onDraw(Canvas canvas)中的Canvas确买,可以另寫一篇文章了。