据说当调用invalidate()时将调用onDraw()。但是,当我看到android源代码时。我没有找到在invalidate()中调用onDraw()的位置。所以我仍然对如何为视图调用onDraw()方法感到困惑。谁能帮我解决这个问题?
答案 0 :(得分:8)
Invalidate
不会直接致电onDraw()
。它会向系统安排一个绘制传递,表示视图需要在将来的某个时刻绘制,这通常几乎是立即的。如果UI线程被阻止,可能需要一些时间。
答案 1 :(得分:8)
绘图
通过遍历树并渲染与无效区域相交的每个视图来处理绘图。因为树是按顺序遍历的,这意味着父母将在他们的孩子之前(即后面)绘制,兄弟姐妹按照他们出现在树中的顺序绘制。如果为View设置了一个可绘制的背景,那么View会在回调它的onDraw()方法之前为你绘制它。
请注意,框架不会绘制不在无效区域中的视图。
要强制绘制视图,请调用invalidate()
。
使整个视图无效。 如果视图可见,将在某个时间点调用onDraw(android.graphics.Canvas)。必须从UI线程调用此方法。要从非UI线程调用,请调用postInvalidate()。
10340 public void invalidate() {
10341 invalidate(true);
10342 }
来源
这是invalidate()实际发生的地方。完全invalidate()会导致绘图缓存失效,但可以将invalidateCache设置为false来调用此函数,以跳过不需要它的情况下的无效步骤(例如,与该节点保持相同维度的组件)相同的内容)。
参数:
invalidateCache此视图的绘图缓存是否也应该无效。这通常适用于完全无效,但如果视图的内容或维度未更改,则可以设置为false。
10354
10355 void invalidate(boolean invalidateCache) {
10356 if (skipInvalidate()) {
10357 return;
10358 }
10359 if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) ||
10360 (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) ||
10361 (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED || isOpaque() != mLastIsOpaque) {
10362 mLastIsOpaque = isOpaque();
10363 mPrivateFlags &= ~PFLAG_DRAWN;
10364 mPrivateFlags |= PFLAG_DIRTY;
10365 if (invalidateCache) {
10366 mPrivateFlags |= PFLAG_INVALIDATED;
10367 mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
10368 }
10369 final AttachInfo ai = mAttachInfo;
10370 final ViewParent p = mParent;
10371 //noinspection PointlessBooleanExpression,ConstantConditions
10372 if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
10373 if (p != null && ai != null && ai.mHardwareAccelerated) {
10374 // fast-track for GL-enabled applications; just invalidate the whole hierarchy
10375 // with a null dirty rect, which tells the ViewAncestor to redraw everything
10376 p.invalidateChild(this, null);
10377 return;
10378 }
10379 }
10380
10381 if (p != null && ai != null) {
10382 final Rect r = ai.mTmpInvalRect;
10383 r.set(0, 0, mRight - mLeft, mBottom - mTop);
10384 // Don't call invalidate -- we don't want to internally scroll
10385 // our own bounds
10386 p.invalidateChild(this, r);
10387 }
10388 }
10389 }
答案 2 :(得分:1)
我必须调用setWillNotDraw(false)。默认情况下,对于ViewGroup的所有子类,它都设置为true。
答案 3 :(得分:0)
看看这个post。这将解释您何时调用onDraw()。
答案 4 :(得分:0)
通过遍历树并渲染每个视图来处理绘图 与无效区域相交。因为树是按顺序遍历的, 这意味着父母将在他们的之前(即后面)抽签 孩子们,兄弟姐妹按照他们出现在树上的顺序画出来。如果 您为View设置了一个可绘制的背景,然后View将绘制它 在回调它的onDraw()方法之前为你服务。
请注意,框架不会绘制不在的框架 无效区域。
要强制绘制视图,请调用invalidate()。
这意味着当UI线程到达它(无效区域)时,它将为该区域调用onDraw()。
答案 5 :(得分:-1)
在以下情况下调用View的onDraw():