Tangram Android 的设计说明

标签: dev | 发表时间:2017-04-29 08:00 | 作者:
出处:http://itindex.net/admin/pagedetail

前言

前段时间开源了团队内的 vlayout项目,从 Github上反馈来看,还是深受欢迎。 但如果仅仅是采用 vlayout 搭建页面,使用起来还不是特别灵活,在此基础之上,我们封装了一套动态化调整界面的模块,命名为 Tangram,现在同样已开源—— Tangram AndroidTangram iOS。我们希望将它打造成某一特定领域的解决方案,提速业务开发。更多关于 Tangram 的介绍可以阅读文章 《页面动态化的基础 —— Tangram》《Tangram是我们对界面动态化的态度》去了解,本文假设你对 Tangram 已经有了大致的理解,然后针对 Android 端的设计做一说明。

基本模型

在前面的文章 《页面动态化的基础 —— Tangram》里,已经重点介绍了 Tangram 里涉及的几个主要概念和模型设计,这里简单重复一下,将页面拆分成三个层次:页面——卡片——组件。页面指的就是整体可滑动页面实体;卡片指的是页面内可按行划分的一个一个独立区块,组件指的是卡片内部一个独立的、业务级别的单元,它可以是一张图,也可以是文字 + 图的组合。因此整体整个页面可以这样描述:一个页面嵌套了多个卡片,一个卡片嵌套了多个组件。Tangram 体系就是规范了这三层的数据结构描述,将其渲染出一张页面。

架构

整体的层次结构如下,我们自底向上进行说明:

  1. 整个 Tangram 框架的页面UI搭建基于 vlayout 和 UltraViewPager。vlayout 之前已经提到过了,用来构建多类型、多布局类型的 RecyclerView; UltraViewPager是 ViewPager 的一种扩展,整合了多种特性,比如横向滑动,竖向滑动,循环滚动等,用来实现 Tangram 内部所需要的轮播滚动卡片;这两个都比较独立,因此独立成库先行开源了,即使不使用 Tangram,也可以单独使用它们。
  2. vlayout 主要提供了一个自定义的 LayoutManager,因此 Tangram 还需要提供一个 RecyclerView 和 Adapter 来才能配合 vlayout 运行。这里的 RecyclerView 可以由外部业务方通过 TangramEngine 注入,也可以内部默认构造。GroupBasicAdapter 则封装了 vlayout 所需要的 Adapter 的逻辑,组件的创建、组件数据的绑定、组件类型的定义等都由它负责。
  3. 在 UI 基础之上的便是各种功能逻辑模块:
    • TangramEngine 是核心类,它负责绑定 RecyclerView 到底层 vlayout,绑定页面数据,操作页面数据(包括增、删、改),还提供注册外部服务的接口。
    • ServiceManager 是服务管理模块,不轮是内部还是外部功能模块,都可以注册到这里,一方面能被 Tangram 内部的其他模块访问到使用,另一方面解耦了框架与业务模块。
    • Bus 是事件总线,它在内部也被注册到 ServieManager,内部模块和业务使用方都可以使用它进行通信,解耦业务代码。
    • DataParser 负责解析数据,它将原始数据解析成卡片、组件的 model 对象。框架里提供的是解析 JSON 数据的解析器,也支持扩展解析其他类型的数据。
    • DataResolver 负责识别卡片、组件并构建对象,解析器解析数据的时候,需要依赖这些 Resolver去识别数据中的卡片或者组件是否合法,Resolver 识别的方式就是去组件库或者卡片库里寻找这些组件是否已经注册过。
  4. 与业务相关性较大的就是组件库、卡片库以及相关业务接口。TangramBuilder 是业务方构建 TangramEngine 的入口。组件库里注册了业务方所需有的组件,Tangram 的实例是一个页面一份,因此每个业务方可以分别注册各自所需要的组件,当业务方使用 Tangram 进行业务开发的时候,主要工作可能就在组件的开发上。卡片库注册的是卡片类型,框架里已经内置了一系列卡片,如果业务方有需要可以单独再注册特殊类型的卡片。而 ClickSupport、ExposureSupport 等都是辅助业务开发的功能模块,前者定义了组件点击处理的接口,后者定义了组件曝光处理的接口。它们都被注册到 ServiceManager 里,业务方在组件或者页面内都可以使用它们。

初始化流程

初始化 Tangram 的流程其实比较简单,无非就是构造 TangramEngine 对象,注册业务组件或者卡片,注册服务模块,绑定 RecyclerView,我们在接入文档—— 接入Tangram代码里详细说明了步骤。这里不一一赘述,在初始化过程中,各个核心模块也都完成了初始化。

运行流程

基本流程图

页面数据示例

   [
  {
    "id": "banner1",
    "type": 1,
    "style": {
      "aspectRatio": 3.223
    },
    "items": [
      {
        "bizId":"item1",
        "type": 110,
        "msg": "info1"
      },
      {
        "bizId":"item2",
        "type": 110,
        "msg": "info2"
      }
    ]
  },
  {
    "type": 1,
    "style": {
      "aspectRatio": 3.223
    },
    "items": [
      {
        "type": 10,
        "imgUrl": "https://gw.alicdn.com/tfs/TB1pdJFQpXXXXbUXpXXXXXXXXXX-750-243.png"
      },
      {
        "type": 10,
        "imgUrl": "https://gw.alicdn.com/tfs/TB1pdJFQpXXXXbUXpXXXXXXXXXX-750-243.png"
      }
    ]
  }
]
  1. 整个 Tangram 对界面的动态调整是通过数据来驱动的,所以首先要将原始数据传递给 TangramEngine,由于集团体系内的接口都采用 JSON 数据,Tangram 框架的默认设计也是接收 JSON 格式的数据,不过也支持通过自定义 DataParser 提前将其他格式的数据解析好之后再传给 TangramEngine。以上述的示例的 JSON 数据为例,一个页面下挂载了一个卡片数组,每个卡片都定义了 id、type、style、items节点;items 内部的数组定义的是组件数据,组件也有type、bizId 等业务字段数据。
  2. 不论是传递原始 JSON 数据给 TangramEngine还是通过直接解析原始数据,都是通过 DataParser 来完成的,它会按照树型结构解析出对应的卡片和组件的 model 对象,解析过程依赖于相应的卡片 Resolver 和组件 Resolver 来识别卡片、组件是否已注册,关键点就是识别 type 字段。若碰到无法识别的 type,则不会解析出对应的 model 对象。
  3. 解析完成之后会得到一个卡片列表,每个列表的卡片 model 元素里持有它所包含的组件列表。
  4. model 列表交给 GroupBasicAdapter 进行处理,首先提取卡片列表,将包含空组件列表的卡片过滤掉,因为它没有东西可以渲染展示,然后创建出 vlayout 所需要的 LayoutHelper 列表,设置它们的样式属性,这样就打通了通过 JSON 数据最终控制布局排版的流程。
  5. 同时将所有的组件 model 提取出来成为一个独立的列表,真正交给 GroupBasicAdapter 去渲染数据,组件 model 列表的大小就是 GroupBasicAdapter 的 item 的大小, RecyclerView 也就直接加载组件视图,卡片相对于只负责了布局逻辑的控制,并没有 UI 实体的承载。
  6. 数据都准备完毕之后,RecyclerView 就驱动 vlayout 里的 LayoutManager 进行渲染和布局。
  7. LayoutManager 首先回调 RecyclerView 内部获取 ViewHolder,若复用池里存在复用的对象,就回调 GroupBasicAdapter 进行数据绑定,否则先回调 GroupBasicAdapter 进行组件 ViewHolder 的创建,然后进行数据绑定。ViewHolder 的创建也是通过 Resolver 内部创建 UI 的模块进行构造。
  8. 这就是 Tangram 渲染页面的整体流程,本身并没有特别复杂的逻辑。而整个框架里的其他模块比如事件总线、ServiceManager 等都是在组件自身绑定数据,处理业务逻辑过程中会使用到,对于这些功能模块的使用,我们也编写了相应的教程文档供参考。

相关文章

本文简要地对 Tangram Android 内部的设计和工作流程进行了说明,有助于对阅读源码的理解。但是建议读者在对 Tangram 有一定了解的基础之上再阅读此文,否则可能有云里雾里的感觉,因为这里涉及到大量的知识点没法完全展开,可以参考以下文章进行了解。

相关 [tangram android 设计] 推荐:

Tangram Android 的设计说明

- - IT瘾-dev
前段时间开源了团队内的 vlayout项目,从 Github上反馈来看,还是深受欢迎. 但如果仅仅是采用 vlayout 搭建页面,使用起来还不是特别灵活,在此基础之上,我们封装了一套动态化调整界面的模块,命名为 Tangram,现在同样已开源—— Tangram Android和 Tangram iOS.

Android设计原则

- - 所有文章 - UCD大社区
译者按: 在 iOS HIG已经强大经典了N年之后,Android终于推出了一套比较系统的 HIG(大概是为了配合Android 4.0 Ice Cream Sandwich). 仔细比较两套HIG的“设计原则”部分,发现完全是截然不同的两种风格. iOS HIG走的是更专业型的路线,描述严谨且有不少的专业词汇(比如Metaphors、Consistency之类的).

八大Android土鳖设计

- corey - 博客园新闻频道
从Android诞生的那天起,这个可爱的小机器人凭借的开源的力量,硬是把iOS挤下市场占有率第一的宝座. 虽然数字占优,但大众的心理中,iOS始终才是最佳体验的移动平台. 诚然,iOS成功的将界面做到了所见即所得的精简化,极致地把手机硬体键减少到一个,从而将用户可操作的范围项,控制在一个很小的空间内,有效降低了用户的学习成本.

Android 4.0设计初体验

- - 所有文章 - UCD大社区
Android系统是目前智能移动设备中增长速度最快的平台,但App的设计却没有形成自己的风格,绝大都数都是ios风格的移植适配. Google 在去年的10月份发布了Android 4.0 的界面规范,在样式、控件上都做了非常个性化的革新,但由于Rom的多样化,设备的不统一,新的4.0设计规范并没有得到广泛的普及.

Android 应用界面设计

- - 互联网的那点事...
与 iOS 相比,Android 系统界面存在各种不协调,应用界面本身缺乏统一的规范. 虽然 Android 的开放性为应用的自主发挥带来了最大的可能性,但如果系统本身能够提供标准的范例,也未必是一件坏事,毕竟许多应用并不一定需要独创的界面. 从 Android 4.0 开始,系统界面在一致性上有了许多改善,那么 Android 应用的界面应该如何设计.

Android 程序框架设计

- - 互联网的那点事
每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心. 通过这种方式,你可以无数次地使用那些已有的解决方案,无需在重复相同的工作. 设计模式是在某种特别的情况下,针对某种问题的某种典型、通用的解决方法. 我们是需要适当了解并学习一些设计模式,在程序开发过程中,总是会涉及到一些框架设计,模块设计之类的东西,如果能很好理解并运行设计模式,你所设计的模块或框架将会要稳定得多,因为这些设计模式它们都是通用的解决方案,是经过实践经验了的.

谈谈Android的一些UI设计

- plidezus - 盒子UI
谈到应用程序设计,对设计师来说,Android就像是房间里的大象. 很多设计师会更希望这是iOS,在那里所有任何人都只需要关心iPhone手机,iPad和App Store. 然后没有人可以忽略Android,它目前已占据智能手机中最大的市场份额,且已经被广泛用于从平板电脑到电子阅读器等各种产品. 总之,谷歌的Android平台正在迅速遍地开花,品牌厂商们很难不注意到.

关于Android的一些设计

- ChamPioNeer - 所有文章 - UCD大社区
谈到应用程序设计,对设计师来说,Android就像是房间里的大象. 很多设计师会更希望这是iOS,在那里所有任何人都只需要关心iPhone手机,iPad和App Store. 然后没有人可以忽略Android,它目前已占据智能手机中最大的市场份额,且已经被广泛用于从平板电脑到电子阅读器等各种产品. 总之,谷歌的Android平台正在迅速遍地开花,品牌厂商们很难不注意到.