最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android View刷新機制實例分析

 更新時間:2016年02月23日 10:34:29   作者:炫_愛羊  
這篇文章主要介紹了Android View刷新機制,結(jié)合實例形式較為詳細的分析了Android的View刷新機制功能、原理與具體使用技巧,需要的朋友可以參考下

本文實例講述了Android View刷新機制。分享給大家供大家參考,具體如下:

一、總體說明

在Android的布局體系中,父View負責(zé)刷新、布局顯示子View;而當(dāng)子View需要刷新時,則是通知父View來完成。

二、代碼分析

1).ViewGroup的addView方法,理解參數(shù)的意義和傳遞

invalidate調(diào)用父類View的方法
addViewInner方法主要做的事情是

view的dispatchAttachedToWindow(AttachInfo info, int visibility)方法

1).View的invalidate方法,這是一個從下第向上回溯的過程,每一層的父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) {
      mLastIsOpaque = isOpaque();
      mPrivateFlags &= ~DRAWN;
      mPrivateFlags |= DIRTY;
      if (invalidateCache) {
        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)用子類的方法完成
      }
    }
  }

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的位置 
    location[CHILD_LEFT_INDEX] = child.mLeft;
    location[CHILD_TOP_INDEX] = child.mTop;
    // If the child is drawing an animation, we want to copy this flag onto
    // 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
    final boolean isOpaque = child.isOpaque() && !drawAnimation && child.getAnimation() != null;
    // 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;
    do {
      View view = null;
      if (parent instanceof View) {
        view = (View) parent;
      }
      if (drawAnimation) {
        if (view != null) {
            view.mPrivateFlags |= DRAW_ANIMATION;
        } else if (parent instanceof ViewRoot) {
            ((ViewRoot) parent).mIsAnimating = true;
        }
      }
        // 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;
      }
      parent = parent.invalidateChildInParent(location, dirty);
    } 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) {
      // 根據(jù)父View的位置,偏移刷新區(qū)域 
      dirty.offset(location[CHILD_LEFT_INDEX] - mScrollX, location[CHILD_TOP_INDEX] - mScrollY);
      final int left = mLeft;
      final int top = mTop;
      //計算實際可刷新區(qū)域 
      if (dirty.intersect(0, 0, mRight - left, mBottom - top) ||
            (mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION) {
        mPrivateFlags &= ~DRAWING_CACHE_VALID;
        location[CHILD_LEFT_INDEX] = left;
        location[CHILD_TOP_INDEX] = top;
        return mParent;
      }
    } 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;
}

這個向上回溯的過程直到ViewRoot那里結(jié)束,由ViewRoot對這個最終的刷新區(qū)域做刷新

ViewRoot.java

public void invalidateChild(View child, Rect dirty) {
}

由ViewRoot對象的performTraversals()方法調(diào)用draw()方法發(fā)起繪制該View樹,值得注意的是每次發(fā)起繪圖時,并不會重新繪制每個View樹的視圖,而只會重新繪制那些“需要重繪”的視圖,View類內(nèi)部變量包含了一個標志位DRAWN,當(dāng)該視圖需要重繪時,就會為該View添加該標志位。

調(diào)用流程

mView.draw()開始繪制,draw()方法實現(xiàn)的功能如下:

1 、繪制該View的背景
2 、為顯示漸變框做一些準備操作(見5,大多數(shù)情況下,不需要改漸變框)
3、調(diào)用onDraw()方法繪制視圖本身   (每個View都需要重載該方法,ViewGroup不需要實現(xiàn)該方法)
4、調(diào)用dispatchDraw ()方法繪制子視圖(如果該View類型不為ViewGroup,即不包含子視圖,不需要重載該
方法)值得說明的是,ViewGroup類已經(jīng)為我們重寫了dispatchDraw ()的功能實現(xiàn),應(yīng)用程序一般不需要重寫該
方法,但可以重載父類函數(shù)實現(xiàn)具體的功能。

4.1 dispatchDraw()方法內(nèi)部會遍歷每個子視圖,調(diào)用drawChild()去重新回調(diào)每個子視圖的draw()方法(注意,這個 地方“需要重繪”的視圖才會調(diào)用draw()方法)。值得說明的是,ViewGroup類已經(jīng)為我們重寫了dispatch

Draw()的功能實現(xiàn),應(yīng)用程序一般不需要重寫該方法,但可以重載父類函數(shù)實現(xiàn)具體的功能。

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android開發(fā)入門與進階教程》、《Android多媒體操作技巧匯總(音頻,視頻,錄音等)》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)

希望本文所述對大家Android程序設(shè)計有所幫助。

相關(guān)文章

  • 淺談Flutter 中漸變的高級用法(3種)

    淺談Flutter 中漸變的高級用法(3種)

    這篇文章主要介紹了淺談Flutter 中漸變的高級用法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Android提高之使用NDK把彩圖轉(zhuǎn)換灰度圖的方法

    Android提高之使用NDK把彩圖轉(zhuǎn)換灰度圖的方法

    這篇文章主要介紹了Android使用NDK把彩圖轉(zhuǎn)換灰度圖的方法,在Android項目開發(fā)中有一定的實用價值,需要的朋友可以參考下
    2014-08-08
  • Android自定義Adapter的ListView的思路及代碼

    Android自定義Adapter的ListView的思路及代碼

    Android自定義Adapter的ListView的思路及代碼,需要的朋友可以參考一下
    2013-05-05
  • Android自定義TabLayout效果

    Android自定義TabLayout效果

    這篇文章主要為大家詳細介紹了Android自定義TabLayout效果的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Android應(yīng)用更新之自動檢測版本及自動升級

    Android應(yīng)用更新之自動檢測版本及自動升級

    這篇文章主要為大家詳細介紹了Android應(yīng)用更新之自動檢測版本及自動升級,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • Android實現(xiàn)彈出登陸框的方案

    Android實現(xiàn)彈出登陸框的方案

    最近在做一個項目,要用到登陸框,幾經(jīng)波折,最后用的是直接將Activity的Theme屬性設(shè)置成Dialog,然后達到了我想要的效果。
    2014-07-07
  • Android Compose衰減動畫Animatable使用詳解

    Android Compose衰減動畫Animatable使用詳解

    這篇文章主要為大家介紹了Android Compose衰減動畫Animatable使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Android多個TAB選項卡切換效果

    Android多個TAB選項卡切換效果

    這篇文章主要介紹了Android多個TAB選項卡切換效果的實現(xiàn)代碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-04-04
  • Android Service功能使用示例代碼

    Android Service功能使用示例代碼

    Service是Android中一個強大的組件,可以用來執(zhí)行需要在后臺進行的任務(wù),通過本文的介紹了解如何在Kotlin中創(chuàng)建和使用Service,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • AndroidStudio項目制作倒計時模塊的方法

    AndroidStudio項目制作倒計時模塊的方法

    本篇文章主要介紹了AndroidStudio項目制作倒計時模塊的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04

最新評論

曲麻莱县| 梁河县| 勃利县| 栾川县| 彰化市| 察隅县| 韩城市| 剑河县| 宾阳县| 上栗县| 永登县| 红安县| 永嘉县| 得荣县| 卫辉市| 从江县| 通河县| 咸阳市| 三穗县| 志丹县| 上犹县| 唐海县| 富裕县| 金溪县| 邛崃市| 常宁市| 河曲县| 涞水县| 东明县| 徐州市| 海伦市| 宁波市| 淅川县| 古蔺县| 稻城县| 昆明市| 湖南省| 山西省| 兰坪| 乌恰县| 敦化市|