原文连接html
在以前的文章《猫客 Tangram 页面内组件的动态化方案》、VirtualView Android实现详解(一)里介绍了 VirtualView 方案,不过内容都侧重与设计和实现原理,在进一步介绍其余细节以前,仍是先来直观感觉下它是什么、它能实现的效果和它的使用方式吧。android
简单讲,就是咱们实现了一系列自定义控件,创建的经过自定义 XML 方式引用这些控件来搭建 UI 视图,而后经过引擎解析 XML 数据并渲染出界面的方案。就比如在 Android 里写 XML 布局文件而后渲染展现,或者写 HTML 文件在浏览器里渲染展现这两种方式。git
在咱们实现的自定义控件里,除了一部分基于系统控件封装实现的控件,还有一类是基于 Canvas 绘制的方式实现的控件,它们依赖与一个实体的宿主控件存在,在最终渲染出来的时候不存在一一对应的实体 View,称之为虚拟化控件,VirtualView 由此得名。github
整套方案的设计必定程度上借鉴吸收了 Android 平台上经过 XML 搭建界面的方式,其中最大的不一样在与简化了不少处理,脱离了平台限制,在 iOS 上也实现了一套方案,能够编写一份模板在两个平台上运行。而且搭配上自定义 XML 数据的动态下发加载能力,能够实现对端上界面视图的动态调整。浏览器
已经开源此方案,能够在 Github 上查看:bash
此方案能够单独使用,而也能够配合 Tangram 使用,关于 Tangram,也能够在 Github 上查看:app
大概须要这么几个过程:编写模板 —— 编译模板 —— 下发到客户端 —— 渲染;工具
FrameLayout
、NImage
、NText
都是内置的控件,设置好各类属性,能够写死也能够经过表达式绑定一个数据字段引用。为了方便上手体验,作了一个 Playground ,能够体验内置基础控件的能力,以及几个业务场景下使用的真实组件,还将编译模板的能力内置到 app 里,能够在 app 里编译 XML 模板并看效果。布局
如下是几个 Playground 里经过 VirtualView 方案绘制的界面:
下载 Playground 并运行,以下操做:
第一次点击若是 /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 工具大更新