要移动视图,我调用setX,setY和其他一些设置宽度和高度的函数,并在每个函数的末尾调用invalidate或requestLayout。因此,每个用户事件多次调用invalidate和requestLayout。这是否会触发每个用户事件的多个布局/绘制?
答案 0 :(得分:3)
当然不是。我们可以在ViewRootImpl中看到代码
void invalidate() {
mDirty.set(0, 0, mWidth, mHeight);
if (!mWillDrawSoon) {
scheduleTraversals();
}
}
使设置脏区无效,并调用scheduleTraversals,它将调用doTraversal。
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
if (mProfile) {
Debug.startMethodTracing("ViewAncestor");
}
performTraversals();
if (mProfile) {
Debug.stopMethodTracing();
mProfile = false;
}
}
}
我们可以在代码中看到mTraversalScheduled标志,如果我们正在计划旅行,触发了无效事件,在doTraversal中mTraversalScheduled为false,因此该方法将直接返回。 因此,并非每个无效事件都称为performTravel,而不是每个名为redraw的无效事件
答案 1 :(得分:1)
是的,确实如此。每次调用invalidate时,视图本身都会重绘!
答案 2 :(得分:1)
每次调用invalidate时,视图本身都会重绘!
这在技术上并不正确。 invalidate
会在视图上设置一个标记,使其有资格重绘。
一个简单的测试是将日志语句放在onDraw
中,然后在循环中调用invalidate
。您将看到每次迭代都没有日志。