使用 Angular Material 开发基于 Material Design 的应用

2015 年 6 月 23 日发布
用户界面设计是应用开发中的重要一环,直接影响最终用户的使用体验。根据不用的设计原则和应用本身的特征,不同应用有不同的用户界面风格。Material Design 是 Google 提出的一套用户界面设计指南。该设计风格已经被应用在 Google 的很多产品上,也可以作为其他应用设计界面时的参考。Angular Material 是 AngularJS 框架之上的 Material Design 的具体实现,由 AngularJS 项目组负责开发和维护。本文对 Angular Material 项目进行详细的介绍。
Material Design 概述
每个应用都应该有自己的用户界面风格。用户界面是一个很复杂的话题,涵盖非常多的内容,如标准组件、色彩搭配、动画效果和交互行为等。大多数应用一般是基于底层框架提供的用户界面库进行基本的定制。如开发 Windows 桌面应用时,可以使用 Windows 提供的标准用户界面库,也可以在标准库的基础上进行定制。在开发 Web 应用时,可以基于流行的 Bootstrap 框架,也可以从零开始定制自己的用户界面风格。一些大公司在内部有自己的用户界面风格规范,保证公司的所有产品有着相似的界面风格,方便用户上手和熟悉。
Material Design 是 Google 提出的用户界面设计指南,涵盖不同平台和设备上的视觉、动作和交互设计。Android 5.0 已经提供了相关的组件和 API 用来创建基于 Material Design 的应用。Google 的其他产品,如 Google Drive、Docs 和 Inbox 等都已经使用了 Material Design 设计风格,其他的很多产品也在陆续进行界面的转换。
Material Design 是一套用户界面的设计指南。它的设计目标是创造一个把经典设计原则和科技的创新与潜能有机地融合起来的视觉语言。开发一个在不同的平台和设备尺寸上拥有统一用户体验的底层系统。
Material Design 的首要设计原则是使用材质(material)作为隐喻。材质的灵感来源于对纸张和墨水的研究,并在触觉体验上做了进一步的提升。材质的表面和边缘可以提供视觉上的线索,帮助用户更快的了解界面元素的用法。光照、表面和移动等元素传递了物体如何在空间中移动和交互的相关信息。第二个原则是采用基于印刷品的设计思路来指导视觉元素的设计,包括字体、网格、间隔、大小、颜色和图片使用等。这些元素用来创建层次结构、含义和焦点。最后一个原则是使用动作来表达含义。动作的作用在于保持用户的注意焦点并保证交互的连贯性。
Material Design 是一个很复杂的用户界面指南。大多数时候开发人员并不需要了解指南的具体细节,只需要使用相关的 API 和库即可。例如,对于 Android 开发人员来说,只需要使用 Android 提供的 Material Design 主题即可。对于 Web 应用来说,可以使用 Polymer 项目提供的 paper elements 库。如果使用 AngularJS,则可以使用本文中要介绍的 Angular Material 项目。这个项目提供了一系列基于 Material Design 的可复用用户界面组件。
Angular Material 使用
Angular Material 框架使用起来非常简单,只需要在页面上添加相应的 JavaScript 和 CSS 文件即可。JavaScript 和 CSS 文件可以从 CDN 直接下载,也可以从官方网站直接下载或通过 Bower 安装。代码清单 1 给出了一个使用 Angular Material 的 Web 应用的骨架代码。需要注意的是,代码清单中使用的是 GitHub 上 master 分支中的最新版本。这是因为本文中介绍的一些组件只在最新版本中可用。如果希望使用稳定版本,可以从 Google 提供的 CDN 下载,目前稳定版本为 0.7.1。
清单 1. 使用 Angular Material 的 Web 应用的骨架代码
布局
在 Web 应用设计和开发中,布局是初始最重要的一环。它确定了页面上不同元素的大小和位置关系。在响应式设计中还需要考虑不同屏幕分辨率之下的不同布局。Angular Material 使用的是 CSS3 规范中定义的弹性盒布局模型(flexbox)。该布局模型作为 W3C 的推荐规范,已经被主流浏览器的新版本所支持,可以在很大程度上简化常见的布局场景的实现,而不必使用过多的 DIV 元素来进行布局。因此在使用 Angular Material 进行布局之前,需要先对弹性盒布局模型有一定的了解。
与 Bootstrap 不同的是,Angular Material 使用 HTML 属性而不是 CSS 类来定义布局。比如,Bootstrap 使用的是类似 class=”col-md-5 col-md-offset-1”来定义布局,而 Angular Material 则采用 layout=”row”来进行定义。在布局容器元素上使用 layout 属性来定义使用的布局方式。布局方式有行布局和列布局两种,分别通过 layout=”row”和 layout=”column”来指定。行布局和列布局分别在水平和垂直方向上排列子元素。布局容器中的子元素可以通过 flex 属性来定义其大小。如果只是添加一个 flex 属性,则该子元素会被自动分配容器元素的可用空间。也可以为 flex 属性指定一个 0 到 100 之间的整数来定义其所占空间的百分数。不过该整数值只能是 33、66 或 5 的倍数。属性 flex-order 用来定义子元素在容器元素中的相对位置。容器元素可以使用 layout-align 属性来定义子元素的对齐方式。该属性的值是两个关键字,分别定义子元素在容器布局方向和相应的垂直方向上的对齐方式。可选的关键字的值分别是 start、center、end、space-around 和 space-between,其含义与弹性盒布局中相同。比如当布局元素的声明是 layout=”row” layout-align=”start center”时,子元素在水平方向上对齐于容器的起始位置,而垂直方向上则居中对齐。
还有一些其他属性可以辅助布局。layout-margin 和 layout-padding 分别用来给布局容器和每个声明了 flex 属性的子元素添加 margin 和 padding。layout-fill 属性强制子元素填充布局容器的可用空间。layout-wrap 属性用来确保 flex 子元素不会超出布局容器的范围。
在响应式设计的支持方面,Angular Material 提供了对应于不同屏幕尺寸范围的属性后缀,如表 1 所示。
表 1. Angular Material 提供的对应于不同屏幕尺寸范围的属性后缀
后缀 | 屏幕尺寸说明 |
---|---|
-sm | 宽度小于 600px |
-gt-sm | 宽度大于 600px |
-md | 宽度在 600px 和 960px 之间 |
-gt-md | 宽度大于 960px |
-lg | 宽度在 960px 和 1200px 之间 |
-gt-lg | 宽度大于 1200px |
比如,使用 layout-sm 属性定义屏幕宽度小于 600px 时的布局方式。属性 hide-gt-lg 表明该元素在屏幕宽度大于 1200px 时不可见。
代码清单 2 给出了一种常见的页面布局方式的 Angular Material 实现。该页面布局分成 4 个部分,分别是 header、sidebar、content 和 footer。最外层的布局容器使用的是 column 布局,把页面垂直划分成 3 个部分。最上面的 header 采用 row 布局,包含 logo 和标题。标题的 H1 元素通过 flex 属性来占满 header 的剩余空间。中间的元素在不同的屏幕尺寸时使用不同的布局:当屏幕宽度大于 600px 时使用 row 布局,水平排列其中包含的 sidebar 和 content,分别占据 20%和 80%的空间;当屏幕宽度小于 600px 时使用 column 布局,垂直排列 sidebar 和 content。最下面的元素是 footer,使用 row 布局,子元素采用居中对齐的方式。中间的元素使用了 flex 属性,因此会占满最外层容器的可用空间。
清单 2. 使用 Angular Material 的典型页面布局
从代码清单 2 中可以看到 Angular Material 布局的简洁性,不需要写任何 CSS 代码就完成了一个响应式的页面布局。如果采用传统的 CSS 来实现相同的布局,则需要编写大量的代码。
主题
Angular Material 使用主题来定义应用中使用的颜色、色调和对比度。主题在设计时遵循 Material Design 中的指导原则,使得在应用中进行色彩搭配变得非常简单。应用只需要从主调色板中选择 3 个色调(hue),从次调色板中选择一个强调色(accent color)即可。调色板是一组色调的集合。Angular Material 提供了 Material Design 指南中内置的调色板,如 red、pink 和 purple 等。对于应用中的不同用户意图(intention),需要指定对应的调色板。Angular Material 中支持 3 种不同的用户意图,分别是 primary、accent 和 warn,分别代表展示给用户的主要、次要和警告界面元素。Angular Material 中的主题实际上是配置不同用户意图对应的调色板以及背景色调色板。
使用 Angular Material 的组件时可以通过 md-primary、md-accent 和 md-warn 来指定组件对应的用户意图分组。对于同一个用户意图分组中的不同组件,可以通过 md-hue-1、md-hue-2 和 md-hue-3 来进一步区分,配置不同的色调。
默认情况下,Angular Material 使用的主题的调色板配置如表 2 所示。
表 2. Angular Material 的默认主题的调色板配置
用户意图 | 调色板名称 |
---|---|
primary | indigo |
accent | pink |
warn | red |
背景色 | grey |
应用可以自由配置所希望使用的主题,如代码清单 3 所示。通过$mdThemingProvider 服务的 theme 方法得到需要配置的主题,再使用 primaryPalette 和 accentPalette 方法分别指定用户意图 primary 和 accent 使用的调色板为 pink 和 orange。还可以使用 warnPalette 和 backgroundPalette 方法来配置另外两种用户意图的调色板。
清单 3. 配置应用使用的主题
对于每个用户意图,需要从对应的调色板中选择 4 个色调,分别作为默认情况、md-hue-1、md-hue-2 和 md-hue-3 使用的色调。默认情况下,用户意图 primary 和 warn 对应的调色板中选择的 4 个色调分别是 500、300、800 和 A100,而 accent 对应调色板中选择的 4 个色调分别是 400、300、800 和 A100。应用也可以定制使用的 4 个色调,如代码清单 4 所示。
清单 4. 配置调色板中不同意图的色调
代码清单 4 中定制了 primary 调色板 pink 的 4 种色调的值,而对于 accent 调色板,则仅指定了默认色调的值,其他色调则使用默认值。
除了使用默认提供的调色板之外,还可以通过$mdThemingProvider.definePalette 方法来重新定义新的调色板,指定其中所有色调的颜色。也可以通过$mdThemingProvider.extendPalette 方法来扩展一个已有的调色板来改变其中某些色调的颜色。
Angular Material 应用在默认情况下使用名为 default 的主题。如果需要使用多个模板,可以通过$mdThemingProvider.theme 方法来创建其他名称的主题。应用通过 md-theme 来指定某个元素及其子元素使用的主题。默认情况下,出于性能方面的考虑,修改 md-theme 的值不会触发主题的切换。如果需要动态切换主题,可以添加 md-theme-watch 声明来强制检查 md-theme 的值。如果需要对整个应用启用动态主题,可以使用$mdThemingProvider.alwaysWatchTheme(true)方法。
组件
Angular Material 的核心是大量可复用的组件,这也是使用 Angular Material 的出发点所在。这些组件可以在应用开发中直接使用。所有组件都是 AngularJS 的 directive,以 md-作为名称前缀。下面分别介绍一些重要的组件。
表单组件
表单组件用来与用户进行交互。md-button 用来创建按钮或超链接。当添加了 ng-href 或 href 属性时, md-button 作为一个超链接出现。如代码清单 5 所示,第一个 md-button 创建的是一个按钮,第二个 md-button 创建的是超链接。
清单 5. 组件 md-button 的使用示例
md-checkbox 用来创建复选框,在使用时和 AngularJS 的 checkbox 是一样的。代码清单 6 给出了使用示例。
清单 6. 组件 md-checkbox 的使用示例
当需要输入文本时,可以使用 md-input、md-textarea 和 md-input-container。md-input-container 是 input 和 textarea 元素的父元素。如果没有 md-input-container,input 和 textarea 无法正常工作。如代码清单 7 所示,在 md-input-container 中直接使用 input 或 textarea 即可。
清单 7. 组件 md-input-container 的使用示例
md-radio-group 和 md-radio-button 用来创建一组单选框。代码清单 8 给出了使用示例。
清单 8. 组件 md-radio-group 和 md-radio-button 的使用示例
md-switch 用来创建切换状态的开关。代码清单 9 给出了使用示例。
清单 9. 组件 md-switch 的使用示例
md-slider 用来创建允许用户选择值的滑动条。代码清单 10 给出了使用示例。
清单 10. 组件 md-slider 的使用示例
布局组件
布局组件用来完成基本的页面布局。md-content 是一个容器元素,可以用来包含需要滚动的内容。md-sidenav 用来创建可以打开和关闭的侧边栏。代码清单 11 给出了使用示例。
清单 11. 组件 md-content 和 md-sidenav 的使用示例
代码清单 11 中创建的是出现在左侧的侧边栏,通过属性 md-component-id 来指定其 ID。toggleSidenav 方法使用$mdSidenav 服务根据侧边栏的 ID 来控制其打开或关闭。
md-tabs 和 md-tab 用来创建标签式布局。md-tabs 作为多个 md-tab 子元素的容器。代码清单 12 给出了使用示例。
清单 12. 组件 md-tabs 和 md-tab 的使用示例
代码清单 12 中创建了 2 个子标签。第一个标签使用 label 属性来指定标签名称,第二个标签使用 md-tab-label 来指定标签名称的 HTML 标记内容。
md-list 和 md-item 分别创建列表和列表中的条目,适合于展示一个列表。代码清单 13 给出了使用示例。
清单 13. 组件 md-list 和 md-item 的使用示例
md-grid-list 和 md-grid-tile 用来创建网格型的布局方式,适合于展现相同类型的对象,如图片缩略图。md-grid-list 创建的是包含多个单元格的网格,而 md-grid-tile 则表示具体的占据单元格的实际内容。每个 md-grid-tile 可以占据任意多个单元格。代码清单 14 给出了使用示例。
清单 14. 组件 md-grid-list 和 md-grid-tile 的使用示例
如代码清单 14 所示,md-grid-list 的 md-cols 属性用来指定网格的列数,而网格的行数取决于其中包含的 md-grid-tile 的数量。md-row-height 属性指定了每行的高度,1:1 的含义是指每个单元格的高度与宽度相同。md-gutter 属性指定单元格之间的分割线的宽度。对于每个 md-grid-tile,通过 md-colspan 和 md-rowspan 属性来指定占据的列数和行数。md-grid-tile 还可以添加 md-grid-tile-header 和 md-grid-tile-footer 子元素来添加单元格的 header 和 footer。
其他组件
md-card 用来创建卡片式的布局,通常用在 md-content 元素中。卡片的宽度是固定的,高度可变。md-toolbar 用来创建工具条,通常出现在 md-content 的上方。md-progress-circular 和 md-progress-linear 用来创建圆形和线形进度条。进度条有确定和不确定两种模式,使用 md-mode 属性来指定。当进度的完成百分比可知时,可以使用确定模式。在确定模式下,需要通过 value 属性来更新进度值。代码清单 15 给出了使用示例。
清单 15. 组件 md-progress-circular 和 md-progress-linear 的使用示例
md-tooltip 用来创建小提示,只需要把 md-tooltip 作为子元素添加到其所描述的元素即可。md-icon 用来创建基于字体或是 SVG 的图标。代码清单 16 给出了使用示例。
清单 16. 组件 md-icon 和 md-tooltip 的使用示例
md-autocomplete 和 md-highlight-text 用来创建自动完成输入框和高亮相关文本。代码清单 17 给出了两者结合起来使用的示例。md-autocomplete 的属性 md-search-text 保存用户输入的文本,md-items 是可供用户选择的选项,一般需要由后台服务根据 md-search-text 保存的用户输入来进行查询。属性 md-item-text 是选项条目对象中对应显示文本的属性名称。md-hightlight-text 指定需要高亮显示的文本。
清单 17. 组件 md-autocomplete 和 md-highlight-text 的使用示例
服务
Angular Material 还提供了一些服务用来创建动态出现的组件。底部菜单栏(bottom sheet)是出现在页面底部的一个快捷操作栏,通常用来包含用户当前可用的操作按钮。$mdBottomSheet 服务的 show 方法用来弹出底部菜单栏。该方法返回一个 promise 对象。$mdBottomSheet 的 hide 或 cancel 方法可以 resolve 或 reject 这个 promise。代码清单 18 给出了底部菜单栏的使用示例。
清单 18. 底部菜单栏的使用示例
在代码清单 18 中,调用$mdBottomSheet.show 时需要提供底部菜单栏的模板,可以是 template 指定的字符串,或是 templateUrl 指定的模板 URL。模板的内容必须包含在<md-bottom-sheet>元素中。还可以通过 controller 提供底部菜单栏绑定的 AngularJS 控制器。对于$mdBottomSheet.show 返回的 promise,可以直接使用 promise 的 then 方法来添加相应的处理逻辑。当点击底部菜单栏的 Done 按钮时,通过$mdBottomSheet.hide 方法来关闭菜单栏,并把结果 Done!作为 promise 的值传回。如果不点击 Done 按钮而是点击其他区域,会自动关闭菜单栏,相应的 promise 会被 reject。
通过$mdDialog 可以创建三种不同的对话框。通过$mdDialog.alert 方法创建提示对话框,$mdDialog.confirm 方法创建确认对话框,而 show 方法则可以创建一个通用的对话框。调用 show 方法时的参数与$mdBottomSheet 的 show 方法相似。关闭对话框时同样使用 hide 或 cancel 方法。
$mdToast 用来创建显示在页面上不同位置上的小提示。$mdToast 的用法类似于$mdBottomSheet 和$mdDialog。在使用 show 方法时通过 position 属性控制出现的位置,可以是 bottom、left、top、right 和 fit 中任意两个的组合。
小结
Google 提出的 Material Design 对于应用的用户界面设计有一定的参考意义。在应用的界面设计中,可以借鉴 Material Design 中的一些很好的设计理念。对于 Web 应用来说,如果基于 AngularJS 来开发,则 Angular Material 是很好的选择。可以很容易就在 Web 应用中实现 Material Design 的效果。本文对 Angular Material 做了详细的介绍,包括页面布局、主题、组件和服务等。
相关主题
参考 Angular Material 官方网站,了解 Angular Material 的更多内容。
参考 Material Design 官方网站,了解更多 Material Design 的内容。
了解弹性盒布局规范的相关内容。
developerWorks Web development 专区:通过专门关于 Web 技术的文章和教程,扩展您在网站开发方面的技能。
developerWorks Ajax 资源中心:这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。
查看 HTML5 专题,了解更多和 HTML5 相关的知识和动向。