欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

AndroidView刷新機(jī)制 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開發(fā)/軟件開發(fā)

知識(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í)提供便捷的支持!

您當(dāng)前位置>首頁(yè) » 新聞資訊 » 技術(shù)分享 >

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)案例查看更多