Material Design:Angular & Flutter (一)
前言
Material Design 是由 Google 所推廣的設計風格,當然 Google 自家的產品也遵循這個風格來設計,而對於它所釋出的開源框架 Angular 與 Flutter 也分別提供 Angular Material 與 Material Components widgets 來協助我們很快速地就可以設計具有 Material Design 的程式,今天我們就來嘗試 Angular 與 Flutter 如何實作。
開發環境
Angular
Angular 開發環境主要需要 Node.js、Angular CLI 最後就是開發工具,筆者是用 Visual Studio Code (簡稱 VS Code)。
安裝完 Node.js 之後我們可以透過指令 npm install -g @angular/cli
來安裝 Angular CLI,接著就是透過 CLI 來建立專案,筆者建立一個名為 material-angular 的專案,並同時加入路由功能(routing),網頁樣式檔採用 SCSS 格式,完整指令如下:ng new material-angular --routing --style scss
接著透過指令 npm start
(或是 ng serve
) 執行專案。
最後透過瀏覽器開啟 http://localhost:4200/,便可看到專案預設網頁。
Flutter
Flutter 開發環境主要需要 Flutter SDK,開發 APP 則需要 Android Studio(Android SDK、模擬器)、Xcode(iOS SDK、模擬器),開發 Web 則需安裝 webdev。
詳細安裝方式請參考官方文件,或是 用 VS Code 建置 Flutter 開發環境 與 Dart 敗部復活賽:Flutter for Web。
接著我們一樣採用 VS Code 來開發,這邊為了方便比較我們使用 Flutter for Web 來開發,我們透過 VS Code 上 Dart & Flutter 的擴充功能來建立一個名為 material_flutter 的專案。
Dart & Flutter 的擴充功能 需要 3.0.0 以上版本。
Angular 專案名稱不允許使用**底線(_),Flutter 專案名稱不允許使用連字符號(-)**。
再來透過指令 webdev serve
來啟動專案。
最後透過瀏覽器開啟 http://localhost:8080,便可看到專案預設網頁。
Material
Angular
Angular 專案要加入 Angular Material 可以參考官方文件 Getting started,比較快的方式是透過 Schematics 指令 ng add @angular/material
來加入,包含網頁模板、動畫、手勢都可以透過設定選項來幫我們一次處理好。
Angular Material 的 Component 都會包覆成獨立的NgModule,我們再依需求個別加入到專案內,比較方便的方式就是建立一個 SharedModule 統一加入到此,也方便後續維護管理,我們建立一個 src\app\shared-material-module.ts
,並先加入所有 Angular Material 的 Component,等到專案建置完之後再移除掉不需要的 Component,程式碼如下:
1 | import { A11yModule } from '@angular/cdk/a11y'; |
可以參考官方的範例的 material-module.ts。
接著將 SharedMaterialModule 加入到 AppModule(src\app\app.module.ts
),這樣 AppModule 下面的 Component 就可以使用,AppModule 的 bootstrap
預設指定 AppComponent 為起始頁面,到這裡我們就已經完成整個專案的設定。
Flutter
Flutter 專案預設已經透過 MaterialApp 幫我們將相關設定都完成了,theme
就跟 CSS 一樣,我們可以修改一些樣式設定,home
則提供預設要載入的 Widget,我們可以將 Flutter 的 Widget 視同 Angular 的 Component,MaterialApp 的 home
就相當於 AppModule 的 bootstrap
。
比較特別的是目前必須手動加入 Material Icons,加入方法是在專案目錄 web\assets\
內建立一個 FontManifest.json
檔案(預設沒有 assets
資料夾,需自行建立)。
並加入下列 JSON 資料:
1 | [ |
版型
Angular
Angular Material 提供了 toolbar 與 sidenav 可以讓我們快速建立一個具有工作欄與側邊欄的版型,修改網頁 src\app\app.component.html
如下:
1 | <mat-drawer-container style="height: 100vh; width:100vw;" autosize> |
為了與 Flutter 效果相近這裡側邊欄採用
mat-drawer
。
執行專案可以看到效果如下:
Flutter
Flutter 提供一個 Scaffold Widget,它預先配置頁面的基本布局,我們只要將對應的 Widget(AppBar、Drawer) 填入就可以完成版型,我直接修改 lib\main.dart
內的 MyHomePage。
程式碼如下:
1 | class MyHomePage extends StatelessWidget { |
執行專案可以看到與 Angular 相同的效果:
路由導覽
Angular
因為我們在建立專案時已經透過 Angular CLI 幫我們建立好路由設定,接下來只要直接使用即可,我們分別透過指令 ng g c page1
與 ng g c page2
建立2個 Component - Page1Component、Page2Component。
接著修改 src\app\page1\page1.component.html
、src\app\page2\page2.component.html
內文字的大小與顏色,以方便識別頁面。
接著在 src\app\app-routing.module.ts
內添加路由規則:
p1
會導覽到 Page1Component。p2
會導覽到 Page2Component。**
其他路徑則切換回p1
,也就是會導覽到 Page1Component。
最後開啟 src\app\app.component.html
,先將 Context 替換為路由插座 router-outlet
,當路由運作時它會將路由規則所對應的 Component 插入到這個路由插座內,接著在 mat-drawer
內加入導覽用的按鈕,我們可以直接透過 routerLink
屬性來設定要導覽的路徑。
重新執行專案,可以看到頁面切換的導覽效果。
Flutter
仿造 Angular 我們一樣建立2個 Widget-Page1、Page2,一樣在側邊欄 Drawer 內加入導覽按鈕。
特別的是在導覽之前會先執行 Navigator.of(context).pop();
,因為 Drawer 不是建立在目前 Widget 內,而是堆疊在目前 Widget 之上,藉由 pop
方法我們先接它移除,另一點是 Flutter 是整頁切換,所以我們必須在每個頁面都使用 Scaffold 這個 Widget 包覆內容。
最後我們在 MyApp 內的 MaterialApp 插入路由規則,要注意的是當 routes
內包含 \
時,外面的 home
屬性就不能設定,反之亦然,擇一使用。
完整程式如下:
1 | import 'package:flutter_web/material.dart'; |
重新執行專案,可以看到頁面切換的導覽效果。
後記
這邊並不是在比較 Angular 與 Flutter 哪一個比較好,使用自己最熟悉的技術就可以,剩下的 Google 相關團隊會讓它們越來越強大。