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

Longerian發表於2018-01-09

原文連結

在之前的文章《貓客 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 上手體驗

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

Playground

為了方便上手體驗,做了一個 Playground ,可以體驗內建基礎控制元件的能力,以及幾個業務場景下使用的真實元件,還將編譯模板的能力內建到 app 裡,可以在 app 裡編譯 XML 模板並看效果。

原始碼地址:

github.com/alibaba/Vir…

以下是幾個 Playground 裡通過 VirtualView 方案繪製的介面:

基礎控制元件演示

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

業務場景演示

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

上手體驗

下載 Playground 並執行,如下操作:

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

  • 點選左圖 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"
}
複製程式碼

虛擬化控制元件演示

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

<?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 上手體驗

體驗一下

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

番外

補充了一篇獨立編譯工具的介紹:天貓客戶端元件動態化方案——VirtualView 工具大更新

相關文章