知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X(jué)表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
AndroidView刷新機(jī)制
發(fā)表時(shí)間:2020-10-19
發(fā)布人:葵宇科技
瀏覽次數(shù):57
一:總體解釋
在Android的構(gòu)造體系中,父View負(fù)責(zé)刷新、構(gòu)造顯示子View;而當(dāng)子View須要刷新時(shí),則是通知父View來(lái)完成。
parent = parent.invalidateChildInParent(location, dirty);
二:代碼分析
1).ViewGroup的addView辦法,理澆愁數(shù)的意義和傳遞
[img]
invalidate調(diào)用父類View的辦法
addViewInner辦法重要做的工作是
[img]
[img]
view的dispatchAttachedToWindow(AttachInfo info, int visibility)辦法
final boolean isOpaque = child.isOpaque() && !drawAnimation && child.getAnimation() != null;
[img]
1).View的invalidate辦法,這是一個(gè)大年夜下第向上回溯的過(guò)程,每一層的父View都將本身的顯示區(qū)域與傳入的刷新 Rect做交集。
void invalidate(boolean invalidateCache) {
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE);
}
if (skipInvalidate()) {
return;
}
if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
(invalidateCache && (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) ||
(mPrivateFlags & INVALIDATED) != INVALIDATED || isOpaque() != mLastIsOpaque) {
mPrivateFlags &= ~DRAWN;
mPrivateFlags |= DIRTY;
mPrivateFlags |= INVALIDATED;
mPrivateFlags &= ~DRAWING_CACHE_VALID;
}
final AttachInfo ai = mAttachInfo;
final ViewParent p = mParent;
//noinspection PointlessBooleanExpression,ConstantConditions
if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
if (p != null && ai != null && ai.mHardwareAccelerated) {
// fast-track for GL-enabled applications; just invalidate the whole hierarchy
// with a null dirty rect, which tells the ViewAncestor to redraw everything
p.invalidateChild(this, null);
return;
}
}
if (p != null && ai != null) {
final Rect r = ai.mTmpInvalRect;
r.set(0, 0, mRight - mLeft, mBottom - mTop);
// Don't call invalidate -- we don't want to internally scroll
// our own bounds
p.invalidateChild(this, r);//調(diào)用子類的辦法完成
if (invalidateCache) {
}
}
}
2)ViewGrop的invalidateChild辦法
public final void invalidateChild(View child, final Rect dirty) {
ViewParent parent = this;
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
final int[] location = attachInfo.mInvalidateChildLocation;
// 須要刷新的子View的地位
4、調(diào)用dispatchDraw ()辦法繪制子視圖(如不雅該View類型不為ViewGroup,即不包含子視圖,不須要重載該 辦法)值得解釋的是,ViewGroup類已經(jīng)為我們重寫了dispatchDraw ()的功能實(shí)現(xiàn),應(yīng)用法度榜樣一般不須要重寫該 辦法,但可以重載父類函數(shù)實(shí)現(xiàn)具體的功能。
location[CHILD_LEFT_INDEX] = child.mLeft;
location[CHILD_TOP_INDEX] = child.mTop;
// ourselves and the parent to make sure the invalidate request goes through
final boolean drawAnimation = (child.mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION;
// Check whether the child that requests the invalidate is fully opaque
} else if (parent instanceof ViewRoot) {
// Mark the child as dirty, using the appropriate flag
// Make sure we do not set both flags at the same time
final int opaqueFlag = isOpaque ? DIRTY_OPAQUE : DIRTY;
View view = null;
if (parent instanceof View) {
view = (View) parent;
}
if (drawAnimation) {
if (view != null) {
}
}
// 根據(jù)父View的地位,偏移刷新區(qū)域
// If the parent is dirty opaque or not dirty, mark it dirty with the opaque
// flag coming from the child that initiated the invalidate
if (view != null && (view.mPrivateFlags & DIRTY_MASK) != DIRTY) {
view.mPrivateFlags = (view.mPrivateFlags & ~DIRTY_MASK) | opaqueFlag;
}
} while (parent != null);
}
}
public ViewParent invalidateChildInParent(final int[] location, final Rect dirty) {
if ((mPrivateFlags & DRAWN) == DRAWN) {
if ((mGroupFlags & (FLAG_OPTIMIZE_INVALIDATE | FLAG_ANIMATION_DONE)) !=
FLAG_OPTIMIZE_INVALIDATE) {
dirty.offset(location[CHILD_LEFT_INDEX] - mScrollX, location[CHILD_TOP_INDEX] - mScrollY);
final int left = mLeft;
final int top = mTop;
// If the child is drawing an animation, we want to copy this flag onto
//計(jì)算實(shí)際可刷新區(qū)域
if (dirty.intersect(0, 0, mRight - left, mBottom - top) ||
(mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION) {
location[CHILD_LEFT_INDEX] = left;
location[CHILD_TOP_INDEX] = top;
return mParent;
mLastIsOpaque = isOpaque();
}
} else {
mPrivateFlags &= ~DRAWN & ~DRAWING_CACHE_VALID;
location[CHILD_LEFT_INDEX] = mLeft;
location[CHILD_TOP_INDEX] = mTop;
dirty.set(0, 0, mRight - location[CHILD_LEFT_INDEX],
mBottom - location[CHILD_TOP_INDEX]);
return mParent;
}
}
return null;
}
mView.draw()開端繪制,draw()辦法實(shí)現(xiàn)的功能如下:
這個(gè)向上回溯的過(guò)程直到ViewRoot那邊停止,由ViewRoot對(duì)這個(gè)最終的刷新區(qū)域做刷新
ViewRoot.java
((ViewRoot) parent).mIsAnimating = true;
public void invalidateChild(View child, Rect dirty) {
}
由ViewRoot對(duì)象的performTraversals()辦法調(diào)用draw()辦法提議繪制該View樹,值得留意的是每次提議畫圖時(shí),并不會(huì)從新繪制每個(gè)View樹的視圖,而只會(huì)從新繪制那些“須要重繪”的視圖,View類內(nèi)部變量包含了一個(gè)標(biāo)記位DRAWN,當(dāng)該視圖須要重繪時(shí),就會(huì)為該View添加該標(biāo)記位。
調(diào)用流程 :
do {
view.mPrivateFlags |= DRAW_ANIMATION;
1 、繪制該View的背景
2 、為顯示漸變框做一些預(yù)備操作(見(jiàn)5,大年夜多半情況下,不須要改漸變框)
3、調(diào)用onDraw()辦法繪制視圖本身 (每個(gè)View都須要重載該辦法,ViewGroup不須要實(shí)現(xiàn)該辦法)
mPrivateFlags &= ~DRAWING_CACHE_VALID;
4.1 dispatchDraw()辦法內(nèi)部會(huì)遍歷每個(gè)子視圖,調(diào)用drawChild()去從新回調(diào)每個(gè)子視圖的draw()辦法(留意, 這個(gè) 處所“須要重繪”的視圖才會(huì)調(diào)用draw()辦法)。值得解釋的是,ViewGroup類已經(jīng)為我們重寫了dispatch Draw()的功能實(shí)現(xiàn),應(yīng)用法度榜樣一般不須要重寫該辦法,但可以重載父類函數(shù)實(shí)現(xiàn)具體的功能。
相關(guān)案例查看更多
相關(guān)閱讀
- 文山小程序開發(fā)
- 汽車報(bào)廢回收管理軟件
- 電商網(wǎng)站建設(shè)
- 報(bào)廢車回收管理系統(tǒng)
- 軟件定制公司
- 云南小程序制作
- 微信小程序開發(fā)入門課程
- 人人商城
- 昆明小程序公司
- 小程序被騙退款成功
- 搜索引擎優(yōu)化
- 昆明小程序開發(fā)
- 百度推廣
- 小程序定制開發(fā)
- 百度小程序公司
- 云南科技公司
- 昆明軟件定制公司
- 網(wǎng)站建設(shè)費(fèi)用
- 云南旅游網(wǎng)站建設(shè)
- 小程序被攻擊
- 網(wǎng)站建設(shè)開發(fā)
- 網(wǎng)站建設(shè)專業(yè)品牌
- 搜索引擎自然排名
- 云南網(wǎng)站建設(shè)服務(wù)
- 云南網(wǎng)站建設(shè)方案 doc
- 網(wǎng)絡(luò)公司聯(lián)系方式
- 小程序的開發(fā)公司
- 云南網(wǎng)站建設(shè)靠譜公司
- 公眾號(hào)模板消息
- 迪慶小程序開發(fā)