Android群英傳知識點回顧——第三章:Android控制項架構與自訂控制項詳解

來源:互聯網
上載者:User

標籤:github   tle   視窗   取出   line   mos   cep   傳遞   源碼   

  • 3.1 Android控制項架構
  • 3.2 View的測量
  • 3.3 View的繪製
  • 3.4 ViewGroup的測量
  • 3.5 ViewGroup的繪製
  • 3.6 自訂View
    • 3.6.1 對現有的空間進行拓展
    • 3.6.2 建立複合控制項
    • 3.6.3 重寫View來實現全新的空間
  • 3.7 自訂ViewGroup
  • 3.8 事件攔截機制分析

控制項大致非為兩類:

  • view控制項:視圖控制項
  • viewGroup控制項:包含多個View控制項,並管理其包含的View控制項
  • 兩者之間的關係:上層控制項負責下層子控制項的測量與繪製,並傳遞互動事件

UI介面架構:

  • Activity都包含一個Window對象,通常由PhoneWindow來實現
  • PhoneWindow將一個DecorView設定為整個應用視窗的根View
    • DecorView為整個Window介面的最頂層View
    • DecorView只有一個子項目為LinearLayout,代表整個Window介面,包含通知欄,標題列,內容顯示欄三塊地區
    • LinearLayout裡有兩個FrameLayout子項目:
      • 標題列顯示介面。只有一個TextView顯示應用的名稱
      • 內容欄顯示介面。就是setContentView()方法載入的布局介面

MeasureSpec類:32位的int值,高2位為測量模式,低30位為測量大小

MeasureSpec模式:

  • EXACTLY:精確模式 ,當控制項的layout_width屬性或layout_height屬性指定為具體值,控制項大小也是該具體值
  • AT_MOST:最大值模式,當控制項layout_width屬性或layout_height屬性指定為warp_content時,控制項的尺寸不要超過父控制項允許的最大尺寸
  • UNSPECIFIED:未指定模式,控制項要多大就多大,通常情況下再繪製自訂View中才會使用

View類預設的onMeasure()方法只支援EXACTLY模式,View需要支援warp_content屬性,那麼就必須重寫onMeasure()方法,來制定warp_content的大小

下面我們通過一個簡單的執行個體,示範如何進行View的測量,首先,需要重寫onMeasure()方法:

可以發現,onMeasure方法調用了父類的onMeasure方法,代碼跟蹤父類onMeasure方法

可以發現,系統最終會調用setMeasuredDimension(int measuredWidth,int measuredHeight)方法將測量後的寬高值設定進去,我們調用自訂的measureWidth()方法和measureHeight()方法,分別對寬高進行重新定義

下面以measureWidth()方法為例:

第一步:從MeasureSpec對象中提取出具體的測量模式和大小

第二步:通過不同的測量模式給出不同的測量值:

  • EXACTLY:使用指定的specSize即可
  • AT_MOST:取出我們指定的大小和SpecSize的最小值
  • UNSPECIFIED:200px

下面這段代碼基本上可以作為模板代碼:

可以發現,當指定warp_content屬性時,View就獲得一個預設值200px

當測量好了一個View之後,我們通過重寫View類中的onDraw()方法來繪圖,要想繪製相應的映像,就必須在Canvas上進行繪製

Canvas就像是一個畫板,我們傳進去一個bitmap,通過這個bitmap建立的Canvas畫布緊緊聯絡在一起,這個過程我們稱之為裝載畫布,這個bitmap用來儲存所有繪製在Canvas上的像素資訊,所以當你在後面調用所有的Canvas.drawxxx方法都會發生在這個bitmap上

ViewGroup在測量時通過遍曆所有子View,從而調用子View的Measure方法來獲得每一個子View的結果

ViewGroup測量完畢後,通常會去重寫onLayout()方法來控制其子View顯示位置的邏輯

ViewGroup通常不需要繪製,如果不是指定ViewGroup的背景顏色,那麼ViewGroup的onDraw()方法都不會被調用,但是,ViewGroup會使用dispatchDraw()方法來繪製子View

在View中通常有以下一些重要的回調方法:

  • onFinishInflate():從XML載入組件後回調
  • onSizeChanged():組件大小改變時回調
  • onMeasure():回調該方法來進行測量
  • onLayout():回調該方法來確定顯示的位置
  • onTouchEvent():監聽到觸摸事件時回調

通常情況下,有以下三種方法來實現自訂的控制項:

  • 對現有的控制項進行拓展
  • 通過組合來實現新的控制項
  • 重寫View來實現全新的控制項

3.6.1 對現有的控制項進行拓展

  • 自訂修改TextView……見經典代碼回顧,案例一
  • 閃動的文字效果……見經典代碼回顧,案例二

3.6.2 建立複合控制項

  • 自訂ToolBar的實現……見經典代碼回顧,案例三

3.6.3 重寫View來實現全新的控制項

  • 弧線展示圖……見經典代碼回顧,案例四
  • 音頻橫條圖……見經典代碼回顧,案例五
  • 自訂ViewGroup,仿ScrollView……見經典代碼回顧,案例六

事件攔截機制三個重要方法

  • dispatchTouchEvent():分發事件
  • onInterceptTouchEvent():攔截事件
  • onTouchEvent():處理事件

舉一個例子說明事件分發機制:

  • ViewGroupA:處於視圖最下層
  • ViewGroupB:處於視圖中介層
  • View:處於視圖最上層

正常的事件分發機制流程:

  • ViewGroupA dispatchTouchEvent
  • ViewGroupA onInterceptTouchEvent
  • ViewGroupB dispatchTouchEvent
  • ViewGroupB onInterceptTouchEvent
  • View dispatchTouchEvent
  • View onTouchEvent
  • ViewGroupB onTouchEvent
  • ViewGroupA onTouchEvent

若ViewGroupB的onInterceptTouchEvent()方法返回true的分發機制流程:

  • ViewGroupA dispatchTouchEvent
  • ViewGroupA onInterceptTouchEvent
  • ViewGroupB dispatchTouchEvent
  • ViewGroupB onInterceptTouchEvent
  • ViewGroupB onTouchEvent
  • ViewGroupA onTouchEvent

若View的onTouchEvent()方法返回true的分發機制流程:

  • ViewGroupA dispatchTouchEvent
  • ViewGroupA onInterceptTouchEvent
  • ViewGroupB dispatchTouchEvent
  • ViewGroupB onInterceptTouchEvent
  • View dispatchTouchEvent
  • View onTouchEvent

若ViewGroupB的onTouchEvent()方法返回true的分發機制流程:

  • ViewGroupA dispatchTouchEvent
  • ViewGroupA onInterceptTouchEvent
  • ViewGroupB dispatchTouchEvent
  • ViewGroupB onInterceptTouchEvent
  • View dispatchTouchEvent
  • View onTouchEvent
  • ViewGroupB onTouchEvent

簡單的說dispatchTouchEvent()和onInterceptTouchEvent()是從下往上一層一層分發下去的,而onTouchEvent()是從上往下一層一層分發下去的

在values檔案夾中建立一個attrs.xml檔案來自訂屬性

開始建立我們的ToolBar

在布局檔案中使用

當使用者不指定具體的比例值時,可以調用以下代碼來設定相應的比例值

自訂的ScrollView沒有系統內建的效能好,畢竟很多因素都沒考慮到,這裡只是適用於練手使用

在布局中使用

經典回顧源碼下載

github:https://github.com/CSDNHensen/QunYingZhuang

Android群英傳知識點回顧——第三章:Android控制項架構與自訂控制項詳解

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.