VirtualView Android 實現詳解(二)—— 虛擬控件的設計與實現

本文介紹 VirtualView 方案裏虛擬化控件的原理,包括尺寸計算與佈局的實現,以及它與原生控件組合使用時的邏輯交互。

相關開源庫

Android

名詞解釋

控件體系與接口設計

先了解一下內置的控件組織關係:

IView 定義協議接口,包括三個過程:

  • comMeasure/onComMeasure:尺寸計算;
  • comLayout/onComLayout:尺寸佈局;
  • comDraw/onComDraw:組件視圖繪製;

系統渲染組件的時候分別會調用這幾個過程。ViewBase 定義控件的基礎屬性;虛擬控件都繼承自 VirtualViewBase,虛擬容器控件都繼承自 Layout,原生控件需要按照本 IView 的協議進行封裝,這個封裝成就是需要繼承自 NativeViewBase;這樣虛擬組件和原生組件都有共同的對外接口,當系統渲染的時候不論虛擬化控件還是原生控件都可以用通用的方式調用,爲混合方式搭建業務組件提供了可能性。

一個虛擬化控件與原生控件混合使用的例子

 

通過在宿主容器裏,掛了一個虛擬容器控件、一個虛擬文本控件、兩個原生圖片控件,可以組合成一個複雜的業務場景下的組件,當它被最終渲染出來的時候,系統只看到宿主容器和連個原生圖片組件,而且系統看到的是宿主容器下直接掛載了圖片控件;如果按照常規的方法開發,這種佈局結構,系統就看到了宿主容器、一層佈局、一個文本、兩個圖片,而且總共有 3 層結構,所以本方案能通過視圖結構扁平化、虛實結合的方式搭建視圖。

 

當這樣一個 VirtualView 掛載到系統佈局容器裏的時候,系統就要對他進行測量、佈局、繪製三個階段,才能顯示出來。而這三個階段觸發的入口便是宿主容器的 onMeasureonLayoutonDraw 三個階段。對於從 XML 里加載出來的整個組件來說,會構造一棵 ViewBase 樹掛載到宿主容器裏,在宿主容器的 onMeasureonLayoutonDraw 三個階段裏調用 ViewBase 樹根節點的 onComMeasureonComLayoutonComDraw,然後再進一步遞歸調用子節點的這些方法,就配合系統顯示流程完成了對應的邏輯。虛擬化控件的尺寸計算協議與 Android 系統的協議一致。對於原生控件來說,IView 的實現就是調用 View 的對應方法,而對於虛擬化控件來說,onComMeasure 過程與實現自定義 View 一樣完成計算邏輯,而 onComLayout 過程需要根據計算結果控制子節點的佈局位置或者繪製位置,而 onComDraw 階段就是操作 canvas 對象,偏移一定位置,然後開始繪製。

實例

 

上圖實例中,圖標都是原生控件,而標題都是虛擬控件。

一個不足之處

如上所述,虛擬化控件的展示其實是依賴於一個宿主容器 View,那麼對於所有虛擬化控件來說,最終都是繪製到同一個宿主容器上的,宿主容器的繪製層級總是在最底層,因此當虛實結合使用的時候,原生控件會擋住虛擬化控件,因此實際的顯示順序會和 XML 裏控件的編寫順序不一致,只有當全部採用虛擬化控件搭建組件的時候,纔不會出現這種情況。

體驗一下

講得再多,不如親自上手體驗一下,可以參考這篇《VirtualView 上手體驗》來體驗。

參考:http://pingguohe.net/2018/03/07/deep-into-virtualview-android-2.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章