《Android開發藝術探索》讀書筆記--第4章 View的工作原理

4.1 初識 ViewRoot 和 DecorView

  1. ViewRoot 對應於 ViewRootImpl 類,連接 WindowManager 和 DecorView 的紐帶
  2. View 的三大流程均通過 ViewRoot 完成
ViewRoot#performTraversals
ViewGroup                             View 
performMeasure   measure  onMeasure   measure
performLayout    layout   onLayout    layout
performDraw      draw     onDraw        draw

  1. DecorView 其實是一個 FrameLayout

4.2 理解 MeasureSpec

  1. MeasureSpec:一個32位int值,高2位代表SpecMode(測量模式),低30位代表SpecSize(規格大小)
模式 簡介
UNSPECIFIED 要多大就多大
EXACTLY 精確模式,match_parent、具體數值
AT_MOST 最大模式, wrap_content
  1. 對於 DecorView ,MeasureSpec 由窗口尺寸和自身的 LayoutParams 共同決定
  2. 普通 View,由 父容器的 MeasureSpec 和自身 LayoutParams 決定。
結論(getChildeMeasureSpec)
View採用固定寬/高,不管父容器 MeasureSpec 是什麼,View的 MeasureSpec 都是 精確模式
View 爲 match_parent,1.父容器是精確模式,View是精確模式,大小是父容器剩餘空間;2.父容器是最大模式,View也是最大模式,大小不會超過父容器剩餘空間
View的寬/高是wrap_content,不管父容器是精確還是最大化,View模式總是最大化,並且不能超過父容器剩餘空間

4.3 View 的工作流程

流程 View ViewGroup
measure(測量) 1.measure就完成測量過程;2.measure是一個final,子類不可重寫,看onMeasure ;3.onMeasure中getMeasuredWidth/Height拿到View寬高,可能不準,需要 onLayout 方法中;4.Activity/View#onWindowFocusChanged;5.view.post();6.ViewTreeObserver(getViewTreeObserver().addOnGlobalLayoutListener);7.view.measure(補充) 1.完成自己測量過程,還要遍歷去調用所有子元素measure方法,各個子元素在measure;2.measureChildren;3.onMeasure 需要子類去重寫
layout(佈局) 1.layout 確定 View 本身位置;2.步驟:setFrame設定View四個頂點位置,接着調用 onLayout 方法,用途是父容器確定子元素位置;3.onLayout 與具體佈局有關,View 和 ViewGroup 均沒有真正實現 onLayout
draw(繪製) 1.繪製背景backgroud.draw(canvas);2.繪製自己(onDraw);3.繪製children(dispatchDraw);4.繪製裝飾;(onDrawScrollBars)。 5.setWillNotDraw,如果一個View不需要繪製任何內容,設置 true,系統優化
view.measure
1.具體的數值
int width = MeasureSpec.makeMeasureSpec(100,MeasureSpec.EXACTLY)
int heigth= MeasureSpec.makeMeasureSpec(100,MeasureSpec.EXACTLY)
view.measure(width ,heigth)

2.wrap_content
int width = MeasureSpec.makeMeasureSpec((1<<30)-1,MeasureSpec.AT_MOST)
int heigth= MeasureSpec.makeMeasureSpec((1<<30)-1,MeasureSpec.AT_MOST)
view.measure(width ,heigth)
  1. getWidth/getMeasureWidth 區別
    在View默認實現中,View測量寬/高和最終寬高相等,只不過測量寬高形成與View的measure,而最終寬高形成View的layout過程。

4.4 自定義 View

4.4.1 自定義View分類

分類
繼承View重寫OnDraw wrap_content,padding
繼承ViewGroup派生特殊Layout 測量、佈局
繼承特定View(tv)
繼承特定ViewGroup(ll)
須知
讓View支持wrap_content 在 onMeasure 中對 wrap_content
如果有必要,讓Viw支持padding draw 中處理 padding,直接繼承 ViewGroup 要在 onMeasure 和 onLayout 彙總 考慮 padding 和 子元素 margin 對其造成的影響,不讓導致 padding 和 子元素 margin 失效
儘量不要在view中使用Handler post
如果有線程或動畫,要及時停止,參考 View#onDetachedFromWindow
View帶有滑動嵌套情形時,需要處理滑動衝突
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章