View.invalidate()/requestLayout()内部核心点?

一般情况

invalidate()调用 只会导致draw()方法的调用,而measure()、layout() 则不会。
requestLayout()则相反,只会 调用measure()、layout(),而不会调用draw()。
总的来说,在这两个函数上的区别很重要的一点就是:layoutRequested 是否为true.

原因:invalidate() 的时候, mLayoutRequested 变量不会被 设置为true。
requestLayout() , requestLayout如果没有改变视图大小,那就不会触发onDraw,其根据layoutRequested为真,measureHierarchy会调用,即measure()调用,之后也就调用了layout()。

与invalidate()相关的两个标志位

PFLAG_INVALIDATEDPFLAG_DRAWING_CACHE_VALID

invalidate()会不断向上查找 ViewParent,直到ViewRootImpl,在这个向上的过程中,只有调用invalidate()方法的View才会将PFLAG_INVALIDATED标志置1,其他的View不会。而所有的View都是将PFLAG_DRAWING_CACHE_VALID置0。

在向下分发draw()的时候,又根据PFLAG_INVALIDATED 位是否为1 且PFLAG_DRAWING_CACHE_VALID位为0 的条件来确定View重绘。

想一想:既然这个过程是先向上查询,再向下分发的过程,那为什么不直接对view绘制,而是这样转一圈?
我的理解是复用的scheduleTraversals()原因。而这个函数同样是requestLayout()该当的核心方法。而requestLayout()则相对于调用的view来说,自己的视图大小改变,必须会涉及到父控件的大小改变,那么就也会导致父View的重新measure、layout、draw()。

你可能感兴趣的:(View.invalidate()/requestLayout()内部核心点?)