天貓客戶端組件動態化的方案——VirtualView 上手體驗

在之前的文章《貓客 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 開發一個組件

大概需要這麼幾個過程:編寫模板 —— 編譯模板 —— 下發到客戶端 —— 渲染;

 

  1. 首先編寫模板,可以通過我們提供的第一版工具 virtualview_tools 編寫,像上圖中 FrameLayoutNImageNText 都是內置的控件,設置好各種屬性,可以寫死也可以通過表達式綁定一個數據字段引用。
  2. 編譯模板,上文提到的引擎加載 XML 並不是直接加載原始 XML 文件,而是先通過 virtualview_tools編譯成一段二進制數據,後綴爲 .out
  3. 下發到客戶端,前兩個步驟都是在客戶端運行時之外進行的,這裏的下發到客戶端有兩種含義,一種是直接將編譯結果打包到客戶端里加載,另一種是發佈到 cdn 上,讓客戶端去下載。
  4. 渲染,方案引擎會加載這份二進制數據,並綁定數據渲染出來。

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 上繪製來展示。

在天貓客戶端裏的應用

體驗一下

講得再多,不如親自上手體驗一下,點擊下載源碼嘗試吧:)

選自:蘋果核 - 天貓客戶端組件動態化的方案​​​​​​​

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