标签:efi date 标记 reg 上传 计算 date() 操作 显示
/**
* Mark the area defined by dirty as needing to be drawn. dirty代表需要重新绘制的脏的区域
* If the view is visible, onDraw(Canvas) will be called at some
point in the future.* This must be called from a UI thread. To call from a non-UI thread, call
postInvalidate().* <b>WARNING:</b> In API 19 and below, this method may be destructive to
dirty.* @param dirty the rectangle矩形 representing表示 the bounds of the dirty region地区
*/
public void invalidate(Rect dirty) {
final int scrollX = mScrollX;
final int scrollY = mScrollY;
invalidateInternal(dirty.left - scrollX, dirty.top - scrollY,
dirty.right - scrollX, dirty.bottom - scrollY, true, false);
}
public void invalidate(int l, int t, int r, int b) {
final int scrollX = mScrollX;
final int scrollY = mScrollY;
//实质还是调用invalidateInternal方法
invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
}
/**
* Invalidate the whole view. 重新绘制整个View
*/
public void invalidate() {
invalidate(true);
}
public void invalidate(boolean invalidateCache) {
invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
}
//这是所有invalidate的终极调用方法
void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,
boolean fullInvalidate) {......
// 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);
//将需要刷新的区域封装到damage中p.invalidateChild(this, damage);
//调用Parent的invalidateChild方法,传递damage给Parent}
......
}
public final void invalidateChild(View child, final Rect dirty) {
ViewParent parent = this;
......
do {
......
//循环层层上级调用,直到ViewRootImpl会返回null
parent = parent.invalidateChildInParent(location, dirty);
......
} while (parent != null);
}
@Override
public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
......
//View调用invalidate最终层层上传到ViewRootImpl后最终触发了该方法
scheduleTraversals();
......
return null;
}
public void postInvalidate() {
postInvalidateDelayed(0);
}
public void postInvalidateDelayed(long delayMilliseconds) {
// We try only with the AttachInfo because there‘s no point in invalidating
// if we are not attached to our window
final AttachInfo attachInfo = mAttachInfo;
//核心,实质就是调用了ViewRootImpl.dispatchInvalidateDelayed方法
if (attachInfo != null) {
attachInfo.mViewRootImpl.dispatchInvalidateDelayed(this, delayMilliseconds);
}
}
public void dispatchInvalidateDelayed(View view, long delayMilliseconds) {
Message msg = mHandler.obtainMessage(MSG_INVALIDATE, view);
mHandler.sendMessageDelayed(msg, delayMilliseconds);
}
public void handleMessage(Message msg) {
......
switch (msg.what) {
case MSG_INVALIDATE:
((View) msg.obj).invalidate();
break;
......
}
......
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
......
//如果mContentParent为空进行一些初始化
if (mContentParent == null) {
installDecor();
}
......
//把我们的view追加到mContentParent
mContentParent.addView(view, params);
......
}
public void addView(View child) {
addView(child, -1);
}
public void addView(View child, int index) {
......
addView(child, index, params);
}
public void addView(View child, int index, LayoutParams params) {
......
//该方法稍后后面会详细分析
requestLayout();
//重点关注!!!
invalidate(true);
......
}
public void requestLayout() {
......
if (mParent != null && !mParent.isLayoutRequested()) {
//从这个View开始向上一直requestLayout,最终到达ViewRootImpl的requestLayout
mParent.requestLayout();
}
......
}
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
//View调用requestLayout最终层层上传到ViewRootImpl后最终触发了该方法
scheduleTraversals();
}
}
invalidate和requestLayout方法源码分析
标签:efi date 标记 reg 上传 计算 date() 操作 显示
原文地址:http://www.cnblogs.com/baiqiantao/p/2a3fccd829120089d24547929175ae29.html