一、起因
遇到这个问题是在一次自定义ViewGroup中重写了onDraw()方法,并且在onDraw中绘制了画面,但是运行过后,画面没有效果。随后自己写了一个简单的Demo,打出日志看了一下绘制流程,如下:
从上面的图片可以清楚的发现在绘制时,只是走了onMeasure,onLayout和dispatchDraw,onDraw方法却没有调用。
随后借鉴了网上的说法,在自定义ViewGroup的xml中设置了一个背景颜色,并运行打印log
这个时候就可以看见在dispatchDraw之前调用了onDraw方法。
两种代码相同的自定义ViewGroup,只是改变了在xml中ViewGroup的背景,一个就会调用onDraw而另外一个则不会,那么为什么在不改变ViewGroup的情况下不走onDraw方法呢?那么又该如何解决这个问题??
带着疑问,我们去源代码中找出原因和解决方法。
二、分析原因
众所周知,ViewGroup是继承自View的,那么直接去查看View。通过代码跟踪发现在ViewGroup中实现OnDraw方法,其实是调用View中的draw(Canvas canvas)方法,如下:
public void draw(Canvas canvas) {
final int privateFlags = mPrivateFlags;
final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
(mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
/*
* 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);
<