在之前的文章《貓客 Tangram 頁面內元件的動態化方案》、VirtualView Android實現詳解(一)裡介紹了 VirtualView 方案,不過內容都側重與設計和實現原理,在進一步介紹其他細節之前,還是先來直觀感受下它是什麼、它能實現的效果和它的使用方式吧。
VirtualView 簡介
什麼是 VirtualView
簡單講,就是我們實現了一系列自定義控制元件,建立的通過自定義 XML 方式引用這些控制元件來搭建 UI 檢視,然後通過引擎解析 XML 資料並渲染出介面的方案。就好比在 Android 裡寫 XML 佈局檔案然後渲染展示,或者寫 HTML 檔案在瀏覽器裡渲染展示這兩種方式。
為什麼叫 VirtualView
在我們實現的自定義控制元件裡,除了一部分基於系統控制元件封裝實現的控制元件,還有一類是基於 Canvas 繪製的方式實現的控制元件,它們依賴與一個實體的宿主控制元件存在,在最終渲染出來的時候不存在一一對應的實體 View,稱之為虛擬化控制元件,VirtualView 由此得名。
與 Android 平臺的佈局檔案有什麼不同
整套方案的設計一定程度上借鑑吸取了 Android 平臺上通過 XML 搭建介面的方式,其中最大的不同在與簡化了很多處理,脫離了平臺限制,在 iOS 上也實現了一套方案,可以編寫一份模板在兩個平臺上執行。並且搭配上自定義 XML 資料的動態下發載入能力,可以實現對端上介面檢視的動態調整。
VirtualView 的主要功能
- 一份模板,在 Android、iOS 兩端執行;
- 提供基礎的原子控制元件與容器控制元件,支援加入自定義控制元件,詳情見文件;
- 支援在 XML 模板裡寫資料繫結表示式動態繫結資料;
- 支援虛擬化的控制元件,混合使用虛擬控制元件和實體控制元件;
- 執行時動態載入 XML 模板資料,動態更新介面結構;
- 註冊事件處理器響應業務邏輯;
關於 VirtualView 的原始碼
已經開源此方案,可以在 Github 上檢視:
此方案可以單獨使用,而也可以配合 Tangram 使用,關於 Tangram,也可以在 Github 上檢視:
VirtualView 使用
使用 VirtualView 開發一個元件
大概需要這麼幾個過程:編寫模板 —— 編譯模板 —— 下發到客戶端 —— 渲染;
- 首先編寫模板,可以通過我們提供的第一版工具 virtualview_tools 編寫,像上圖中
FrameLayout
、NImage
、NText
都是內建的控制元件,設定好各種屬性,可以寫死也可以通過表示式繫結一個資料欄位引用。 - 編譯模板,上文提到的引擎載入 XML 並不是直接載入原始 XML 檔案,而是先通過 virtualview_tools 編譯成一段二進位制資料,字尾為 out。
- 下發到客戶端,前兩個步驟都是在客戶端執行時之外進行的,這裡的下發到客戶端有兩種含義,一種是直接將編譯結果打包到客戶端里載入,另一種是釋出到 cdn 上,讓客戶端去下載。
- 渲染,方案引擎會載入這份二進位制資料,並繫結資料渲染出來。
Playground
為了方便上手體驗,做了一個 Playground ,可以體驗內建基礎控制元件的能力,以及幾個業務場景下使用的真實元件,還將編譯模板的能力內建到 app 裡,可以在 app 裡編譯 XML 模板並看效果。
原始碼地址:
以下是幾個 Playground 裡通過 VirtualView 方案繪製的介面:
基礎控制元件演示
業務場景演示
上手體驗
下載 Playground 並執行,如下操作:
- 點選左圖 Parse XML ,進入右圖;
- 點選『點選編譯/sdcard/virtualview.xml檔案』按鈕,就會實時編譯一份原始 XML 並載入到記憶體裡,然後渲染出一個 View,貼到下方,如右圖綠色框內演示的那樣。
第一次點選如果 /sdcard/virtualview.xml 檔案不存在,會從 Playground 的asset 裡拷貝一份檔案過去,圖上展示的就是預設的效果; 使用者可以自己傳一份 XML 檔案到路徑 /sdcard/virtualview.xml,或者基於 Playground 裡的修改,然後編譯執行。
預設模板程式碼
上圖中的模板檔案和資料來源碼分別如下:(一個橫向線性佈局加一個圖和一個文字,除了固定的寬高,動態資料通過表示式從 JSON 資料裡獲取)
<?xml version="1.0" encoding="utf-8"?>
<VHLayout
flag="flag_exposure|flag_clickable"
orientation="H"
layoutWidth="match_parent"
layoutHeight="wrap_content">
<NImage
id="1"
src="${logoUrl}"
layoutMarginLeft="8"
layoutMarginRight="8"
layoutMarginTop="8"
layoutMarginBottom="8"
layoutWidth="32"
layoutHeight="32"/>
<NText
id="2"
text="${title}"
layoutGravity="v_center"
gravity="${style.text-align}"
textSize="${style.font-size}"
textColor="${style.color}"
layoutWidth="match_parent"
layoutHeight="wrap_content"/>
</VHLayout>
複製程式碼
{
"style": {
"text-align": "h_center",
"font-size": "20",
"color": "#FF5000"
},
"title": "超高性 99.9% 的使用者覺得很快",
"logoUrl": "https://gw.alicdn.com/tfs/TB1yGIdkb_I8KJjy1XaXXbsxpXa-72-72.png"
}
複製程式碼
虛擬化控制元件演示
<?xml version="1.0" encoding="utf-8"?>
<VHLayout
flag="flag_exposure|flag_clickable"
orientation="V"
layoutWidth="match_parent"
layoutHeight="wrap_content">
<VHLayout
flag="flag_exposure|flag_clickable"
orientation="H"
layoutWidth="match_parent"
layoutHeight="wrap_content">
<NImage
id="1"
src="${logoUrl}"
layoutMarginLeft="8"
layoutMarginRight="8"
layoutMarginTop="8"
layoutMarginBottom="8"
layoutWidth="32"
layoutHeight="32"/>
<NText
id="2"
text="${title}"
layoutGravity="v_center"
gravity="${style.text-align}"
textSize="${style.font-size}"
textColor="${style.color}"
layoutWidth="match_parent"
layoutHeight="wrap_content"/>
</VHLayout>
<VHLayout
flag="flag_exposure|flag_clickable"
orientation="H"
layoutWidth="match_parent"
layoutHeight="wrap_content">
<VImage
id="1"
src="${logoUrl}"
layoutMarginLeft="8"
layoutMarginRight="8"
layoutMarginTop="8"
layoutMarginBottom="8"
layoutWidth="32"
layoutHeight="32"/>
<VText
id="2"
text="${title}"
layoutGravity="v_center"
gravity="${style.text-align}"
textSize="${style.font-size}"
textColor="${style.color}"
layoutWidth="match_parent"
layoutHeight="wrap_content"/>
</VHLayout>
</VHLayout>
複製程式碼
如上圖及模板程式碼所示,第一行內容圖片(NImage)和文字(NText)都是實體 View,而第二行內容圖片(VImage)和文字(VText)都是虛擬化的實現,通過在宿主容器的 Canvas 上繪製來展示。
在天貓客戶端裡的應用
體驗一下
講得再多,不如親自上手體驗一下,點選下載原始碼嘗試吧:)
番外
補充了一篇獨立編譯工具的介紹:天貓客戶端元件動態化方案——VirtualView 工具大更新