在之前的文章《貓客 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 模板並看效果。
源碼地址:
https://github.com/alibaba/Virtualview-Android/tree/master/app
以下是幾個 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 上繪製來展示。
在天貓客戶端裏的應用
體驗一下
講得再多,不如親自上手體驗一下,點擊下載源碼嘗試吧:)
選自:蘋果核 - 天貓客戶端組件動態化的方案