在上一篇博客中我们开始就提到了两组方法,其中scrollTo()和scrollBy()在上一篇博客中已经说的比较详细了,但是对于另一组invalidate()系列的方法只是说明他们重新调用draw方法绘制界面,并没有说明他们究竟是怎样一步一步实现对界面进行重绘的。在这篇博客中就为大家分析一下invalidate()系列方法重绘界面的过程,同时也说明另一个在自定义控件中会用到而且和的方法invalidate()相似的方法requestLayout()方法。
首先看到invalidate()方法,不管我们是自定义继承至View还是继承至ViewGroup的控件,invalidate()方法都是调用的View类中的,查看invalidate()方法源码:
public void invalidate() {
invalidate(true);
}
接着查看:
// 参数表示是否跳过无效的步骤
// 如果一个控件的大小和内容都未发生改变,可以设置为false的表示跳过无效步骤
// 使用了默认修饰符,只有同一个包下的才可以调用,在不同包中即使是子类也不可以调用,所以开发者不能调用
void invalidate(boolean invalidateCache) {
invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
}
接着查看invalidateInternal()方法的代码:
void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,
boolean fullInvalidate) {
if (mGhostView != null) {
mGhostView.invalidate(true);
return;
}
// 判断是否需要跳过重新绘制,
// 当需要重绘的控件是不可见的并且没有运行一个动画,就不需要重新绘制
if (skipInvalidate()) {
return;
}
if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)
|| (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID)
|| (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED
|| (fullInvalidate && isOpaque() != mLastIsOpaque)) {
// 是否全部重绘
if (fullInvalidate) {
mLastIsOpaque = isOpaque();
mPrivateFlags &= ~PFLAG_DRAWN;
}
mPrivateFlags |= PFLAG_DIRTY;
// 是否跳过无效的步骤
if (invalidateCache) {
mPrivateFlags |= PFLAG_INVALIDATED;
mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
}
// Propagate th