protectedbooleansetFrame(int left, int top, int right, int bottom){ boolean changed = false; if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) { changed = true;
// Remember our drawn bit int drawn = mPrivateFlags & PFLAG_DRAWN;
int oldWidth = mRight - mLeft; int oldHeight = mBottom - mTop; int newWidth = right - left; int newHeight = bottom - top; boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight);
// Propagate the damage rectangle to the parent view. //把需要重绘的区域传递给父容器 final AttachInfo ai = mAttachInfo; final ViewParent p = mParent; if (p != null && ai != null && l < r && t < b) { final Rect damage = ai.mTmpInvalRect; damage.set(l, t, r, b); //调用父容器的方法,向上传递事件 p.invalidateChild(this, damage); } ... } }
/** * Don't call or override this method. It is used for the implementation of * the view hierarchy. */ publicfinalvoidinvalidateChild(View child, final Rect dirty){
//设置 parent 等于自身 ViewParent parent = this;
final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { ... int opaqueFlag = isOpaque ? PFLAG_DIRTY_OPAQUE : PFLAG_DIRTY;
/** * @return true if drawing was successful, false if an error occurred */ privatebooleandrawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff, boolean scalingRequired, Rect dirty){
// Draw with software renderer. final Canvas canvas; try { finalint left = dirty.left; finalint top = dirty.top; finalint right = dirty.right; finalint bottom = dirty.bottom;
canvas = mSurface.lockCanvas(dirty);
// The dirty rectangle can be modified by Surface.lockCanvas() //noinspection ConstantConditions if (left != dirty.left || top != dirty.top || right != dirty.right || bottom != dirty.bottom) { attachInfo.mIgnoreDirtyState = true; }
// TODO: Do this in native canvas.setDensity(mDensity); } catch { ... }