1.为什么继承ViewGroup,draw(canvas: Canvas?)会不被调用?
在View中判断需要刷新控件的updateDisplayListIfDirty()方法中
public RenderNode updateDisplayListIfDirty() {
...
// Fast path for layouts with no backgrounds
if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
dispatchDraw(canvas);
drawAutofilledHighlight(canvas);
if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().draw(canvas);
}
if (debugDraw()) {
debugDrawFocus(canvas);
}
} else {
draw(canvas);
}
...
}
当(mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW会直接跳过当前控件的draw(canvas)方法。
而mPrivateFlags会在setBackgroundDrawable(Drawable background),setForeground(Drawable foreground),setDefaultFocusHighlight(Drawable highlight),setFlags(int flags, int mask)这四个方法中被设置成PFLAG_SKIP_DRAW。
public void setBackgroundDrawable(Drawable background) {
...
if (background != null) {
...
} else {
/* Remove the background */
mBackground = null;
if ((mViewFlags & WILL_NOT_DRAW) != 0
&& (mDefaultFocusHighlight == null)
&& (mForegroundInfo == null || mForegroundInfo.mDrawable == null)) {
mPrivateFlags |= PFLAG_SKIP_DRAW;
}
...
}
..
}
public void setForeground(Drawable foreground) {
...
if (foreground != null) {
...
} else if ((mViewFlags & WILL_NOT_DRAW) != 0 && mBackground == null
&& (mDefaultFocusHighlight == null)) {
mPrivateFlags |= PFLAG_SKIP_DRAW;
}
...
}
private void setDefaultFocusHighlight(Drawable highlight) {
...
if (highlight != null) {
...
} else if ((mViewFlags & WILL_NOT_DRAW) != 0 && mBackground == null
&& (mForegroundInfo == null || mForegroundInfo.mDrawable == null)) {
mPrivateFlags |= PFLAG_SKIP_DRAW;
}
...
}
除了修改背景和前景以外,还可以用setFlags(int flags, int mask)方法来修改,而View里面有一个已经写好的方法setWillNotDraw(boolean willNotDraw),只要调用这个方法设置为false,那么ViewGroup的draw(canvas: Canvas?)方法就会被调用。
/**
* If this view doesn't do any drawing on its own, set this flag to
* allow further optimizations. By default, this flag is not set on
* View, but could be set on some View subclasses such as ViewGroup.
*
* Typically, if you override {@link #onDraw(android.graphics.Canvas)}
* you should clear this flag.
*
* @param willNotDraw whether or not this View draw on its own
*/
public void setWillNotDraw(boolean willNotDraw) {
setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);
}
网友评论