<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ##4.1 初始ViewRoot和DecorView (1)`ViewRoot`對應`ViewRootImpl`類,它是連接`WindowManager`和`DecorView`的紐帶,View的三大流程均通過ViewRoot來完成。 (2)`ActivityThread`中,Activity創建完成后,會將DecorView添加到Window中,同時創建ViewRootImpl對象,并建立兩者的關聯。 (3)View的繪制流程從ViewRoot的`performTraversals`方法開始,經過`measure`、`layout`和`draw`三大流程。 (4)`performMeasure`方法中會調用`measure`方法,在`measure`方法中又會調用`onMeasure`方法,在onMeasure方法中會對所有的子元素進行measure過程,這個時候measure流程就從父容器傳遞到子元素了,這樣就完成了一次measure過程,layout和draw的過程類似。 (書中175頁畫出詳細的圖示) (5)measure過程決定了view的寬高,在幾乎所有的情況下這個寬高都等同于view最終的寬高。layout過程決定了view的四個頂點的坐標和view實際的寬高,通過`getWidth`和`getHeight`方法可以得到最終的寬高。draw過程決定了view的顯示。 (6)DecorView其實是一個FrameLayout,其中包含了一個豎直方向的LinearLayout,上面是標題欄,下面是內容欄(id為`android.R.id.content`)。 ## 4.2 理解MeasureSpec (1)`MeasureSpec`和`LayoutParams`的對應關系 在view測量的時候,系統會將LayoutParams在父容器的約束下轉換成對應的MeasureSpec,然后再根據這個MeasureSpec來確定View測量后的寬高。 MeasureSpec不是唯一由LayoutParams決定的,LayoutParams需要和父容器一起才能決定view的MeasureSpec,從而進一步確定view的寬高。對于DecorView,它的MeasureSpec由窗口的尺寸和其自身的LayoutParams來決定;對于普通view,它的MeasureSpec由父容器的MeasureSpec和自身的LayoutParams來共同決定。 (2)普通view的MeasureSpec的創建規則 (書中182頁列出詳細的表格) 當view采用固定寬高時,不管父容器的MeasureSpec是什么,view的MeasureSpec都是精確模式,并且大小是LayoutParams中的大小。 當view的寬高是`match_parent`時,如果父容器的模式是精確模式,那么view也是精確模式,并且大小是父容器的剩余空間;如果父容器是最大模式,那么view也是最大模式,并且大小是不會超過父容器的剩余空間。 當view的寬高是`wrap_content`時,不管父容器的模式是精確模式還是最大模式,view的模式總是最大模式,并且大小不超過父容器的剩余空間。 ## 4.3 view的工作流程 (1)view的measure過程和Activity的生命周期方法不是同步執行的,因此無法保證Activity執行了`onCreate`、`onStart`、`onResume`時某個view已經測量完畢了。如果view還沒有測量完畢,那么獲得的寬高就都是0。下面是四種解決該問題的方法: 1.`Activity/View # onWindowFocusChanged`方法 `onWindowFocusChanged`方法表示view已經初始化完畢了,寬高已經準備好了,這個時候去獲取寬高是沒問題的。這個方法會被調用多次,當Activity繼續執行或者暫停執行的時候,這個方法都會被調用。 2.`view.post(runnable)` 通過post將一個runnable投遞到消息隊列的尾部,然后等待Looper調用此runnable的時候,view也已經初始化好了。 3.`ViewTreeObserver` 使用`ViewTreeObserver`的眾多回調方法可以完成這個功能,比如使用`onGlobalLayoutListener`接口,當view樹的狀態發生改變或者view樹內部的view的可見性發生改變時,`onGlobalLayout`方法將被回調。伴隨著view樹的狀態改變,這個方法也會被多次調用。 4.`view.measure(int widthMeasureSpec, int heightMeasureSpec)` 通過手動對view進行measure來得到view的寬高,這個要根據view的LayoutParams來處理: `match_parent`:無法measure出具體的寬高; `wrap_content`:如下measure,設置最大值 ~~~ int widthMeasureSpec = MeasureSpec.makeMeasureSpec((1 << 30) - 1, MeasureSpec.AT_MOST); int heightMeasureSpec = MeasureSpec.makeMeasureSpec((1 << 30) - 1, MeasureSpec.AT_MOST); view.measure(widthMeasureSpec, heightMeasureSpec); ~~~ 精確值:例如100px ~~~ int widthMeasureSpec = MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY); int heightMeasureSpec = MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY); view.measure(widthMeasureSpec, heightMeasureSpec); ~~~ (2)在view的默認實現中,view的測量寬高和最終寬高是相等的,只不過測量寬高形成于measure過程,而最終寬高形成于layout過程。 (3)draw過程大概有下面幾步: 1.繪制背景:`background.draw(canvas)`; 2.繪制自己:`onDraw()`; 3.繪制children:`dispatchDraw`; 4.繪制裝飾:`onDrawScrollBars`。 ## 4.4 自定義view (1)繼承view重寫onDraw方法需要自己支持`wrap_content`,并且`padding`也要自己處理。繼承特定的View例如TextView不需要考慮。 (2)盡量不要在View中使用Handler,因為view內部本身已經提供了`post`系列的方法,完全可以替代Handler的作用。 (3)view中如果有線程或者動畫,需要在`onDetachedFromWindow`方法中及時停止。 (4)處理好view的滑動沖突情況。 接下來是原書中的自定義view的示例,推薦閱讀[源碼](https://github.com/singwhatiwanna/android-art-res/blob/master/Chapter_4/src/com/ryg/chapter_4/ui/CircleView.java)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看