[Angular Material完全攻略] Day 04 - MatButton、MatButtonToggle和MatRipple

今天我们要来介绍Angular Material按钮(button)的使用方法,按钮可以说是一切互动介面的基本,只要按下了按钮,所有事情都可能会发生,也因此设计良好的按钮是非常重要的,除了让事情发生外,也要让使用者能够明确的知道按钮背后的意义,今天就让我们看看Material Design中按钮的设计思维,以及如何在Angular Material如何轻易地达到这些设计的目标吧!

关于Material Design的按钮

Material Design的Button的设计指南中,按钮主要分为3种类型:

  1. 扁平化按钮(Flat Button) :一个基本的文字矩形,通常使用在dialog、toolbar之中,颜色很简单,在不是以按钮为主的元件中这些按钮扮演著配角的角色,让你不会过度的注意它,但在需要时又能明显知道它的存在
  2. 凸起的按钮(Raised Button) :具有阴影且明显的按钮,在画面上会比较有立体感、甚至是一个明显的色块,会跟其他扁平化的元素产生不同空间的感觉,因此在视觉上会非常具有存在感,适合用在需要提醒使用者按下的地方,例如加入购物车这种的按钮就很适合使用。
  3. 浮动的动作按钮(Floatng Action Button) :Floating Action Button是Material Design中非常重要且独特的一种设计方式,重要到在官方的设计指南中有独立的一个完整篇章在介绍它,它通常会固定在整个萤幕或是某个功能区快的固定位置,用来提醒使用者这个按钮具有(或包含)画面上最常使用到的功能,也可以想像成是一种捷径的概念。为了凸显这种按钮的存在,又要避免存在有著突兀的感觉,因此会设计成圆形但不会太佔空间的按钮,也因此基本上按钮中只会放置Icon,比较少会放文字。
image.png

除了扁平化的按钮是为了在画面上有协调的感觉以外,其他的按钮设计都是为了凸显自身的存在,因此在设计上也都会呈现阴影的感觉,让视觉上更加清楚。

在Angular Material中使用按钮

在Angular Material中,所有的按钮都放置在MatButtonModule中,因此使用时记得加入这个Module

import { MatButtonModule } from '@angular/material';

@NgModule({
  ...
  imports: [
    ...,
    MatButtonModule],
  ...
})
export class AppModule {}

由于按钮在网页上的存在极具意义,Angular Material在设计上并未把按钮封装成component,而是以directive的方式附著在<button><a>标籤上,并透过样式的变化让原来的<button><a>标籤具有Material Design的风格。

扁平化按钮(mat-button)

扁平化按钮是最基本的按钮样式,使用上非常简单,在原来的button或a标籤上加上mat-button即可

<button mat-button>我是按钮</button>

这时候在画面上看起来会完全没有按钮的感觉,而只是个文字的存在,但当滑鼠移到按钮上时,则会看到比较深色的背景,按下去时则会产生互动的涟漪效果。

当然,我们也可以使用color属性来改变按钮的颜色,同时也可以使用disabled属性禁止按钮被点选。

  <button mat-button>我是按钮</button>
  <button mat-button color="primary">Primary</button>
  <button mat-button color="accent">Accent</button>
  <button mat-button color="warn">Warn</button>
  <button mat-button disabled>Disabled</button>
  <a mat-button>Link</a> <!-- 放在a tag裡面也没问题 -->

效果如下:

image.png

凸起的按钮(mat-raised-button)

比起扁平化的按钮,凸起的按钮会有明显的反差,也会有比较深的阴影效果,以凸显按钮的存在,凸起的按钮需要加上mat-raised-button

  <button mat-raised-button>我是raised按钮</button>
  <button mat-raised-button color="primary">Primary</button>
  <button mat-raised-button color="accent">Accent</button>
  <button mat-raised-button color="warn">Warn</button>
  <button mat-raised-button disabled>Disabled</button>
  <a mat-button>Link</a>

效果如下:


image.png

Icon按钮

要替按钮加上Icon本身是一件很简单的事情,在标籤内加上<mat-icon>就可以了,例如:

<button mat-raised-button color="primary"><mat-icon>thumb_up</mat-icon> 我有Icon</button>

效果如下:

image.png

不过如果我想只想要icon,不要搭配文字呢?

<button mat-raised-button color="primary"><mat-icon>thumb_up</mat-icon></button>

结果:

image.png

这样有点问题的是,左右留白太多了好像有点浪费空间,毕竟只想要icon的按钮通常就是为了能够节省空间啊!这时候可以使用专门为了呈现icon的mat-icon-button来解决这个问题:

<button mat-icon-button color="primary"><mat-icon>thumb_up</mat-icon></button>

结果:

image.png

看起来就单纯许多,如果希望凸显这个按钮,我们可以先用mat-raised-button将它变成更明显的按钮,在使用mat-icon-button改变成为左右不留白的样式

<button mat-raised-button mat-icon-button color="primary"><mat-icon>thumb_up</mat-icon></button>

结果:

image.png

可以看到按钮的留白就移除了,边角也变成了圆形的,只有Icon的单一按钮用这样的呈现方式感觉还不错!

浮动的动作按钮(mat-fab / mat-min-fab)

接下来要介绍的是预设就是圆形的floating action button,我们使用到mat-fab这个directive:

  <button mat-fab>
    <mat-icon>thumb_up</mat-icon>
  </button>
  <button mat-fab color="primary">
    <mat-icon>thumb_up</mat-icon>
  </button>
  <button mat-fab color="accent">
    <mat-icon>thumb_up</mat-icon>
  </button>
  <button mat-fab color="warn">
    <mat-icon>thumb_up</mat-icon>
  </button>
  <button mat-fab disabled>
    <mat-icon>thumb_up</mat-icon>
  </button>

效果如下:

image

可以发现一件事情,在没有指定颜色的时候,mat-fab的样式与accent颜色是一样的,可以见得floating action button本身的设计理念就是为了凸显它的存在感,这刚好与accent的概念是用来强调这裡有东西的颜色概念一样,不得不佩服Angular Material设想得非常周到。

mat-fab本身应为圆形且要凸显的效果,整个按钮看起来会比较大,但对于比较小的区块中要使用时反而会显得太过突兀,这时候我们也可以使用mat-mini-fab来产生比较小的floating action button

  <button mat-mini-fab>
    <mat-icon>thumb_up</mat-icon>
  </button>
  <button mat-mini-fab color="primary">
    <mat-icon>thumb_up</mat-icon>
  </button>
  <button mat-mini-fab color="accent">
    <mat-icon>thumb_up</mat-icon>
  </button>
  <button mat-mini-fab color="warn">
    <mat-icon>thumb_up</mat-icon>
  </button>
  <button mat-mini-fab disabled>
    <mat-icon>thumb_up</mat-icon>
  </button>

跟原来的按钮比较效果如下:

image.png

mat-mini-fab产生的按钮样式跟一般的按钮高度就会一样,因此看起来会跟使用mat-raised-button加上mat-icon-button的组合技有一样的效果,不过在语义上则是不一样的东西。

以上就是整个Angular Material中的按钮基本用法,并不会非常困难,主要就是几个directives,依照不同的情境决定使用方式;接下来要介绍的是类似按钮却不是按钮的东西,叫做按钮开关(button toggle)。

按钮开关(button toggle)

按钮开关基本上不是按钮,反而比较类似checkbox,偏偏它又不像checkbox是表单控制项,可以搭配ngModel使用,因此单一的按钮开关使用上会比较没有意义,而是使用一个群组式的按钮开关,应用层面比较广

基本的Button Toggle(mat-button-toggle)

mat-button-toggle放在MatButtonToggleModule中,使用前记得加入这个Module,加入后我们可以直接在画面上使用

<mat-button-toggle>我是个开关</mat-button-toggle>

结果如下:

image

可以看到每次点下去,就有切换开关的效果。mat-button-toggle这个component本身还有如checked、value、disabled等属性可以使用,我们将在下一个Button Toggle Group中一起混著使用

搭配Button Toggle Group(mat-button-toggle-group)

mat-button-toggle-group可以放置多个mat-button-toggle,并且依照被选取的mat-button-toggle来决定自己的值是什麽,我们可以设计一个简单的画面如下:

<mat-button-toggle-group #formatAlignGroup="matButtonToggleGroup">
  <!-- button toogle所代表的值 -->
  <mat-button-toggle value="left">
    <mat-icon>format_align_left</mat-icon>
  </mat-button-toggle>
  <!-- 预设被选取 -->
  <mat-button-toggle value="center" checked="true">
    <mat-icon>format_align_center</mat-icon>
  </mat-button-toggle>
  <mat-button-toggle value="right">
    <mat-icon>format_align_right</mat-icon>
  </mat-button-toggle>
  <!-- 不允许选择的button toggle -->
  <mat-button-toggle value="justify" disabled>
    <mat-icon>format_align_justify</mat-icon>
  </mat-button-toggle>
</mat-button-toggle-group>
<div>对齐方式为:{{ formatAlignGroup.value }}</div>

<!-- 加上multiple,则裡面的mat-buttong-toggle可以複选 -->
<!-- 加上vertical="true", 改变排列方式 -->
<mat-button-toggle-group multiple vertical="true">
  <mat-button-toggle value="bold" #buttonToggleBold>
    <mat-icon>format_bold</mat-icon>
  </mat-button-toggle>
  <mat-button-toggle value="italic" checked="true" #buttonToggleItalic>
    <mat-icon>format_italic</mat-icon>
  </mat-button-toggle>
  <mat-button-toggle value="underlined" checked="true" #buttonToggleUnderlined>
    <mat-icon>format_underlined</mat-icon>
  </mat-button-toggle>
</mat-button-toggle-group>
<div>粗体:{{ buttonToggleBold.checked }}、斜体:{{ buttonToggleItalic.checked }}、底线:{{ buttonToggleUnderlined.checked }}</div>

在上面的程式中,第一段ButtonToggleGroup中我们使用value为每个mat-button-toggle中设定所属的值,并且设定checked="true"来设定预设选取的效果、以及disabled来设定禁止点选,接著透过template reference取得ButtonToggleGroup的value值,也就是裡面真正被开启的按钮值。

第二段ButtonToggleGroup中我们加入了mutiple,让裡面的ButtonToggle可以複选,另外加上了vertical="true"改变排列方式,不过在複选时我们无法直接使用buttonToggleGroup.value来取得值,因此只能各自取得裡面的ButtonToggle的选取状态。

效果如下:

image

关于ButtonToggleGroup中mutiple的设定,值得注意的是没有加上mutiple时,我们可以直接取用其中的value,来得到被选取的状态,同时也支援使用ngModel;加上mutiple后,由于不会有资料传入value中,因此ngModel也因此无法使用了。

详细的其他属性可以参考ButtonToggle的API文件

涟漪效果(mat-ripple)

介绍一个官方文件没有提到,但官方source code的demo app有示范的一个有趣的东西,也就是涟漪效果,这个效果主要用在按钮上面,在许多其他元件也可看到这个特效的踪影,在刚刚的介绍中我们也看到了按下按钮后会产生的特效;实际上这个特效有写成一个directive,让我们可以在不同地方使用,而且能调整许多细节。

首先加入MatRippleModule后,我们先来个简单的版本,直接用一个div并加上mat-ripple这个directive就好!

<div class="demo-ripple-container" mat-ripple>

我们在这边加上了一个class的设定

.demo-ripple-container {
  height: 150px;
  width: 200px;
  position: relative;
  transition: all 200ms linear;
  border: 1px solid black;
}

position和transaition是必要的,其他可以依照情况设定,只要有这样的设定,立刻就可以为我们的画面加上涟漪效果啦!

image

mat-ripple的其他属性

除了基本的设定外,mat-ripple还有其他属性可以设定,让画面呈现更加不一样,以下是mat-ripple的主要属性

  • matRippleCentered:true代表不管滑鼠在元件上的哪裡点下去,都会从中心点开始产生涟漪。

  • matRippleDisabled:true代表取消元件上的涟漪效果。

  • matRippleUnbounded:true代表涟漪的效果扩大后会超过元件之外。

    image
  • matRippleRadius:涟漪产生的大小,数值越大大表大小越大。

  • matRippleCol:涟漪的颜色。

  • matRippleSpeedFactor:涟漪扩散的速度,数值越大速度越快

例如以下程式码,我们可以在画面上产生数个粉红色且扩散速度慢的涟漪点。

<div class="demo-ripple-container" mat-ripple
[matRippleCentered]="false"
[matRippleDisabled]="false"
[matRippleUnbounded]="false"
[matRippleRadius]="10"
[matRippleColor]="'pink'"
[matRippleSpeedFactor]="0.5"></div>

结果如下:

image

从程式触发涟漪的效果

我们也能从程式裡面去直接触发涟漪的产生,如下:

export class AppComponent implements OnInit {
  @ViewChild(MatRipple) ripple: MatRipple;

  triggerRipple() {
    const point1 = this.ripple.launch(0, 0, { color: 'pink', centered: true, persistent: true, radius: 50 });
    const point2 = this.ripple.launch(0, 0, { color: 'yellow', centered: true, persistent: true, radius: 20 });

    setTimeout(() => {
      point1.fadeOut();      
    }, 500);
  }

  clearRipple() {
    this.ripple.fadeOutAll();
  }
}

ripple.launch的前两个参数为涟漪点产生的位置,但目前这个计算会跑掉,所以我们在第三个参数中设定相关属性时将centered设为true,强制从中心点开始,另外这边我们加了一个persistent为true,代表涟漪点产生后不会自动淡出。我们可以透过fadeOutAll()把所有涟漪点都淡出。

效果如下:

image

是不是很有趣啊!

本日小结

今天我们介绍了非常实用的元件-按钮,按钮可以说是一切互动的开始,透过按钮我们可以期待会有事情发生,而在Material Design中对于按钮的设计也是一门学问,如何在低调与奢华的按钮之间选择,影响了使用者对画面的观感。

除此之外我们也介绍了开关型的按钮,这种按钮在特定的情境下会非常实用。

最后我们额外介绍了文件目前没有的涟漪效果,这个效果在许多元件中都能看到,因此拉出来变成一个独立的directive也是件正常不过的事情,除此之外mat-ripple还能有许多更细部的设定,让效果更加丰富。

在介绍过几个实用的元件及功能后,明天开始我们就要开来组合各种元件,并且完成各式各样的画面啦!!

本日的程式码GitHub:https://github.com/wellwind/it-ironman-demo-angular-material/tree/day-04-mat-button
分支:day-04-mat-button

相关资源

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容