[譯] MDC-103 Flutter: Material Theming 的顏色、形狀、高度和型別(Flutter)

Material 元件(MDC)幫助開發者實現 Material Design。MDC 由谷歌團隊的工程師和 UX 設計師創造,為 Android、iOS、Web 和 Flutter 提供很多美觀實用的 UI 元件。
現在可以使用 MDC 來為你的應用程式定製遠比以前獨特的樣式。Material Design 近期的更新使得設計師和開發者可以更靈活地表達他們的產品理念。
在教程 MDC-101 和 MDC-102 中,你使用 Material 元件(MDC)為一個名為 Shrine 的銷售服裝和家居用品的電子商務應用程式構建基礎。這個應用的使用者使用流程包括一個開始的登陸頁面,然後導航使用者前往展示商品的主螢幕。
你將構建一個
在本教程中,你將會使用以下屬性來定製 Shrine 應用:
- 顏色(Color)
- 排版(Typography)
- 高度(Elevation)
- 形狀(Shape)
- 佈局(Layout)


這是四篇教程中的第三篇,來引導你構建 Shrine 應用。
其餘教程可在這裡找到:
到 MDC-104 的最後,你將會構建一個像這樣的應用:

本教程中使用到的 MDC-Flutter 元件和子系統
- 主題(Theme)
- 排版(Typography)
- 高度(Elevation)
- 圖片列表(Image list)
你將需要
- Flutter SDK
- 安裝好 Flutter 外掛的 Android Studio,或者你喜歡的程式碼編輯器
- 示例程式碼
要在 iOS 上構建和執行 Flutter 應用程式,你需要滿足以下要求:
- 執行 macOS 的計算機
- Xcode 9 或更新版本
- iOS 模擬器,或者 iOS 物理裝置
要在 Android 上構建和執行 Flutter 應用程式,你需要滿足以下要求:
- 執行 macOS、Windows 或 Linux 的計算機
- Android Studio
- Android 模擬器(隨 Android Studio 一起提供)或 Android 物理裝置
2. 安裝 Flutter 環境
前提條件
要開始使用 Flutter 開發移動應用程式,你需要:
- Flutter SDK
- 裝有 Flutter 外掛的 IntelliJ IDE,或者你喜歡的程式碼編輯器
Flutter 的 IDE 工具適用於Android Studio、 IntelliJ IDEA Community(免費)和 IntelliJ IDEA Ultimate 。

要在 iOS 上構建和執行 Flutter 應用程式,你需要滿足以下要求:
- 執行 macOS 的計算機
- Xcode 9 或更新版本
- iOS 模擬器,或者 iOS 物理裝置

要在 Android 上構建和執行 Flutter 應用程式,你需要滿足以下要求:
- 執行 macOS,Windows 或者 Linux 的計算機
- Android Studio
- Android 模擬器(隨 Android Studio 一起提供)或 Android 物理裝置
重要提示:如果連線到計算機的 Android 手機上出現“允許 USB 除錯”對話方塊,請啟用 始終允許從此計算機 選項,然後單擊 確定 。
在繼續本教程之前,請確保你的 SDK 處於正確的狀態。如果之前安裝過 Flutter SDK,則使用 flutter upgrade
來確保 SDK 處於最新版本。
flutter upgrade 複製程式碼
執行 flutter upgrade
將自動執行 flutter doctor
。如果這是首次安裝 Flutter 且不需升級,那麼請手動執行 flutter doctor
。檢視顯示的所有 ✓ 標記;這將會下載你需要的任何缺少的 SDK 檔案,並確保你的計算機配置無誤以進行 Flutter 的開發。
flutter doctor 複製程式碼
3. 下載教程初始應用程式
從 MDC-102 繼續?
如果你完成了 MDC-102,那麼本教程所需程式碼應該已經準備就緒,跳轉到 調整顏色 一步。
從頭開始?
下載初始應用程式
此入門程式位於 material-components-flutter-codelabs-103-starter_and_102-complete/mdc_100_series
目錄中。
...或者從 GitHub 克隆它
要從 GitHub 克隆此專案,請執行以下命令:
git clone https://github.com/material-components/material-components-flutter-codelabs.git cd material-components-flutter-codelabs git checkout 103-starter_and_102-complete 複製程式碼
更多幫助: 從 GitHub 上克隆儲存庫
正確的分支
教程 MDC-101 到 104 連續構建。所以當你完成 103 的程式碼後,它將變成 104 教程的初始程式碼!程式碼被分成不同的分支,你可以使用以下命令將它們全部列出:
git branch --list
要檢視完整程式碼,請切換到 104-starter_and_103-complete
分支。
建立你的專案
以下步驟預設你使用的是 Android Studio (IntelliJ)。
建立專案
material-components-flutter-codelabs flutter create mdc_100_series

開啟專案
-
開啟 Android Studio。
-
如果你看到歡迎頁面,單擊 開啟已有的 Android Studio 專案 。

- 導航到
material-components-flutter-codelabs/mdc_100_series
目錄並單擊開啟,這將開啟此專案。
在構建專案一次之前,你可以忽略在分析中見到的任何錯誤。

- 在左側的專案面板中,刪除測試檔案
../test/widget_test.dart

- 如果出現提示,安裝所有平臺和外掛更新或 FlutterRunConfigurationType,然後重新啟動 Android Studio。

提示:確保你已安裝Flutter 和 Dart 外掛。
執行初始程式
以下步驟預設你在 Android 模擬器或裝置上進行測試。你也可以在 iOS 模擬器或裝置上進行,只要你安裝了 Xcode。
- 選擇裝置或模擬器
如果 Android 模擬器尚未執行,請選擇 Tools -> Android -> AVD Manager 來 建立您裝置並啟動模擬器 。如果 AVD 已存在,你可以直接在 IntelliJ 的裝置選擇器中啟動模擬器,如下一步所示。
(對於 iOS 模擬器,如果它尚未執行,通過選擇 Flutter Device Selection -> Open iOS Simulator 來在你的開發裝置上啟動它。)

- 啟動 Flutter 應用:
- 在你的編輯器視窗頂部尋找 Flutter Device Selection 下拉選單,然後選擇裝置(例如,iPhone SE / Android SDK built for )。
- 點選 執行 圖示(

如果你無法成功執行此應用程式,停下來解決你的開發環境問題。嘗試導航到 material-components-flutter-codelabs
;如果你在終端中下載 .zip 檔案,導航到 material-components-flutter-codelabs-...
然後執行 flutter create mdc_100_series
。
成功!上一篇教程中 Shrine 的登陸頁面應該在你的模擬器中運行了。你可以看到 Shrine 的 logo 和它下面的名稱 "Shrine"。

如果應用沒有更新,再次單擊 “Play” 按鈕,或者點選 “Play” 後的 “Stop”。
點選“Next”來檢視上一教程中的主螢幕。

4. 調整顏色(Color)
一個代表著 Shrine 品牌的配色方案已經建立好了。設計師希望你在 Shrine 應用中實現這個配色方案。
首先,讓我們在專案裡匯入這些顏色。
建立 colors.dart
在 lib
目錄下新建一個名為 colors.dart
的 dart 檔案。匯入 Material 元件並新增 Color 常量:
import 'package:flutter/material.dart'; const kShrinePink50 = const Color(0xFFFEEAE6); const kShrinePink100 = const Color(0xFFFEDBD0); const kShrinePink300 = const Color(0xFFFBB8AC); const kShrinePink400 = const Color(0xFFEAA4A4); const kShrineBrown900 = const Color(0xFF442B2D); const kShrineErrorRed = const Color(0xFFC5032B); const kShrineSurfaceWhite = const Color(0xFFFFFBFA); const kShrineBackgroundWhite = Colors.white; 複製程式碼
自定義調色盤(Color palette)
此顏色主題由設計師自選顏色進行建立(如下圖所示)。它包含 Shrine 的品牌色並應用於 Material 主題編輯器,由此衍生出的完整的調色盤。(這些顏色並非來自 2014 Material color palette。)
Material 主題編輯器使用以數字表示的色度(shade)對顏色進行分類,每種顏色都有 50、100、200、... 一直到 900 等幾個色度。Shrine 僅僅使用 50、100 和 300 色度的粉色調以及 900 色度的棕色調。
譯者注:色度:色彩深淺、明暗的程度。


每個部件的顏色引數都對應此模板內的顏色。例如,文字框在接收輸入時的修飾顏色應該是主題的 Primary color。如果該顏色不合適(易於與背景區分),請改用 PrimaryVariant。
Colors 類
kShrineBackgroundWhite
的值來自於 Colors 類。這個類包含常見的顏色值,例如白色。它還包含 2014 color palette 作為 MaterialColor 類。
MaterialColor 類
在 'material/colors.dart' 中找到的 MaterialColor 類(子類是 ColorSwatch )是一組包含 14 或更少種由原色變換成的顏色,比如 14 種不同色度的紅色、綠色、淺綠或石灰色。這就類似於你在油漆店裡見到的漸變色色卡。
這些顏色是在 2014 Material 指南中提出的,並且在當前指南( 顏色系統(Color System) )以及 MDC-Flutter 中仍然可用。要在程式碼裡訪問它們,只需呼叫基礎色後接色度(通常為 100 的倍數)即可。例如,Pink 400 可通過 Colors.pink[400]
檢索到。
你完全可以將這些調色盤運用到你的設計和程式碼上。如果已經有屬於品牌自己的配色,也可以使用調色盤生成工具或者Material 主題編輯器來生成自己的配色。
現在我們有想用的顏色了。我們可以將它應用到 UI 上。我們將通過設定應用於 MaterialApp 例項頂部層次結構的 ThemeData 部件來實現。
定製 ThemeData.light()
Flutter 包含一些內建主題。light 主題就是其中之一。與其從零開始製作一個 ThemeData 部件,我們不如拷貝 light 主題然後修改其中的一部分屬性來為我們的應用進行定製。
拷貝 ThemeData 例項
我們在預設的 light ThemeData 中呼叫 copyWith()
,然後傳入一些自定義屬性值( copyWith()
在 Flutter 中是一個常用方法,你會在很多類和部件中看到它)。這個命令返回與呼叫它的例項匹配的部件例項,但是替換了一些指定的值。
為什麼不例項化一個 ThemeData 然後設它的屬性呢?當然可以!如果我們繼續構建我們的程式,這將很有意義。由於 ThemeData 擁有 大量 的屬性,為了節省時間,我們的教程將從修改一個有吸引力的主題的可見值入手。當我們稍後嘗試使用替代主題時,我們將從 MDC-Flutter 附帶的 ThemeData 開始。
在Flutter 文件中瞭解更多有關 ThemeData 的資訊。
讓我們在 app.dart
中匯入 colors.dart
。
import 'colors.dart'; 複製程式碼
然後將以下內容新增到 app.dart 的 ShrineApp 類 之外 的地方:
// TODO:構建 Shrine 主題(103) final ThemeData _kShrineTheme = _buildShrineTheme(); ThemeData _buildShrineTheme() { final ThemeData base = ThemeData.light(); return base.copyWith( accentColor: kShrineBrown900, primaryColor: kShrinePink100, buttonColor: kShrinePink100, scaffoldBackgroundColor: kShrineBackgroundWhite, cardColor: kShrineBackgroundWhite, textSelectionColor: kShrinePink100, errorColor: kShrineErrorRed, // TODO:新增文字主題(103) // TODO:新增圖示主題(103) // TODO:修飾輸入內容(103) ); } 複製程式碼
現在在應用的 build()
函式最後(在 MaterialApp 部件中)將 theme:
設成我們的新主題:
// TODO:新增主題(103) return MaterialApp( title: 'Shrine', // TODO:將 home: 改為 HomePage frontLayer(104) home: HomePage(), // TODO:讓 currentCategory 欄位持有 _currentCategory(104) // TODO:向 frontLayer 傳遞 _currentCategory(104) // TODO:將 backLayer 欄位值改為 CategoryMenuPage(104) initialRoute: '/login', onGenerateRoute: _getRoute, theme: _kShrineTheme, // 新加程式碼 ); 複製程式碼
點選執行按鈕,你的登陸頁面看起來應該是這個樣子的:

你的主螢幕看起來應該像這樣:

有關顏色(Color)和主題(Theme)的注意事項:
- 你可以自定義 UI 中的顏色以便詮釋你的品牌特色。
- 從兩種顏色(主要和次要顏色)開始製作調色盤,使用不同色度的顏色。或者使用 Material Design 調色盤工具生成。
- 不要忘記排版的顏色!
- 確保文字與背景的顏色對比度適中(主文字為 3:1,副文字為 4:1)
5. 修改排版和標籤樣式
除了更改顏色,設計師還為我們提供了特定的排版。Flutter 的 ThemeData 包含 3 種文字主題。每個文字主題都是一個文字樣式的集合,如 “headline” 和 “title”。我們將為我們的應用使用幾種樣式並更改一些值。
定製文字主題
為了將字型匯入專案,我們必須將它們新增到 pubspec.yaml 檔案中。
在 pubspec.yaml 中,在 flutter:
標籤下新增以下內容:
# TODO:引入字型(103) fonts: - family: Rubik fonts: - asset: fonts/Rubik-Regular.ttf - asset: fonts/Rubik-Medium.ttf weight: 500 複製程式碼
現在你可以訪問並使用 Rubik 字型了。
pubspec 檔案故障排除
如果你剪下並貼上上面的宣告程式碼,你可能會在執行 pub get 時遇到錯誤。如果出現錯誤,請先刪除前導空格,然後使用空格縮排替換空格。
fonts: 複製程式碼
之前有兩個空格,
family: Rubik 複製程式碼
之前有四個空格,以此類推。
如果你看到 Mapping values are not allowed here(此處不允許存在對映值) ,檢查問題所在行以及上方的其他行的縮排。
app.dart
中,在 _buildShrineTheme()
之後新增如下內容:
// TODO:構建 Shrine 文字主題(103) TextTheme _buildShrineTextTheme(TextTheme base) { return base.copyWith( headline: base.headline.copyWith( fontWeight: FontWeight.w500, ), title: base.title.copyWith( fontSize: 18.0 ), caption: base.caption.copyWith( fontWeight: FontWeight.w400, fontSize: 14.0, ), ).apply( fontFamily: 'Rubik', displayColor: kShrineBrown900, bodyColor: kShrineBrown900, ); } 複製程式碼
這需要一個 文字主題 並且更改 headline、titles 和 captions 的樣式。
用這種方式應用 fontFamily
僅將更改應用於 copyWith()
欄位中指定的(headline, title, caption)排版比例。
對於某些字型,我們正在為其設定自定義 FontWeight。 FontWeight 部件在 100s 上具有方便的值。在字型中,w500(權值(weight)500)是中等大小,w400 是常規大小。
使用新的文字主題
文字主題
文字主題是確保應用內所有文字一致且可讀的有效方法。例如,文字主題樣式可以是黑色或白色,具體取決於主題主要顏色的亮度。這可確保文字與背景形成適當的對比,使其始終可讀。
在Flutter 文件中瞭解有關文字主題的更多資訊。
在 _buildShrineTheme
的 errorColor 後新增以下內容:
// TODO:新增文字主題(103) textTheme: _buildShrineTextTheme(base.textTheme), primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme), accentTextTheme: _buildShrineTextTheme(base.accentTextTheme), 複製程式碼
在點選停止按鈕後再次點選允許按鈕。
登陸頁面和主螢幕中的文字看起來有些不同 —— 有些使用 Rubik 字型,其他文字則呈現棕色,而不是黑色或白色。

有關排版的注意事項:
- 當選擇文字字型時注意,為小號和主體文字選擇清晰的字型,而不是注重某種樣式。
- 用作標題的、大號文字的字型應該用來表達或強調品牌。
注意到沒有,我們的圖示仍然時白色的,這是因為它們有一個另外的主題。
使用自定義的主要圖示主題
將其新增到 _buildShrineTheme()
函式:
// TODO: 新增圖示主題(103) primaryIconTheme: base.iconTheme.copyWith( color: kShrineBrown900 ), 複製程式碼
單擊執行按鈕。

應用欄的圖示變成棕色的了!
收縮文字
我們的標籤有點太大了。
在 home.dart
中,改變 children:
欄位最內部的列:
// TODO:改變最內部的列(103) children: <Widget>[ // TODO:處理溢位標籤(103) Text( product == null ? '' : product.name, style: theme.textTheme.button, softWrap: false, overflow: TextOverflow.ellipsis, maxLines: 1, ), SizedBox(height: 4.0), Text( product == null ? '' : formatter.format(product.price), style: theme.textTheme.caption, ), // 新增程式碼結尾 ], 複製程式碼
居中放置文字
我們想要將標籤居中,並將文字與每張卡片的底部,而不是圖片的底部對齊。
將標籤移動到主軸的結尾(底部)並將它們改為居中:
// TODO:將標籤對齊底部和中心(103) mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, 複製程式碼
儲存專案。

已經很接近了,但是文字還不是在卡片的居中位置。
更改父列的橫軸對齊:
// TODO:卡片內容居中(103) crossAxisAlignment: CrossAxisAlignment.center, 複製程式碼
儲存專案。你的應用應該看起來像這樣:

這樣看起來好多了。
主題化文字框
你也可以使用 InputDecorationTheme 來主題化文字框的修飾。
在 app.dart
中的 _buildShrineTheme()
方法裡,指定 inputDecorationTheme:
的值:
// TODO:修飾輸入內容(103) inputDecorationTheme: InputDecorationTheme( border: OutlineInputBorder(), ), 複製程式碼
現在,文字框有一個 filled
修飾。讓我們移除它。
在 login.dart
內,移除 filled: true
值:
// 移除 filled: true 值(103) TextField( controller: _usernameController, decoration: InputDecoration( // 移除 filled: true labelText: 'Username', ), ), SizedBox(height: 12.0), TextField( controller: _passwordController, decoration: InputDecoration( // 移除 filled: true labelText: 'Password', ), obscureText: true, ), 複製程式碼
單擊停止按鈕,然後單擊執行(為了從頭開始啟動應用程式)。你的登陸頁面在使用者名稱文字框處於活動狀態時(當你輸入時)應該是這樣的:

在正確的強調色文字框修飾和浮動佔位符渲染中輸入。但是我們不能輕易地看到它。給那些無法區分足夠高色彩對比度畫素的人帶設定了障礙。(更多詳細資訊,參看 Material 指南中有關“無障礙顏色”的色彩文章。)讓我們建立一個特殊類來覆蓋部件的強調顏色,將其變成設計師在上面的顏色主題中為我們提供的 PrimaryVariant。
在 login.dart
中任何其他類的範圍之外新增以下內容:
// TODO:新增強調色覆蓋(103) class AccentColorOverride extends StatelessWidget { const AccentColorOverride({Key key, this.color, this.child}) : super(key: key); final Color color; final Widget child; @override Widget build(BuildContext context) { return Theme( child: child, data: Theme.of(context).copyWith(accentColor: color), ); } } 複製程式碼
下一步,將 AccentColorOverride
應用到文字框。
在 login.dart
中,匯入 colors:
import 'colors.dart'; 複製程式碼
使用新的部件包裝 Username 文字框:
// TODO:使用 AccentColorOverride 包裝 Username(103) // [Name] AccentColorOverride( color: kShrineBrown900, child: TextField( controller: _usernameController, decoration: InputDecoration( labelText: 'Username', ), ), ), 複製程式碼
同樣使用新的部件包裝 Password 文字框:
// TODO:使用 AccentColorOverride 包裝 Password(103) // [Password] AccentColorOverride( color: kShrineBrown900, child: TextField( controller: _passwordController, decoration: InputDecoration( labelText: 'Password', ), ), ), 複製程式碼
單擊執行按鈕。

6. 調整高度
現在你已經為頁面設定了與 Shrine 相匹配的特定顏色和排版,讓我們看看展示 Shrine 產品的卡片。這些卡片位於導航旁邊的白色平面上。
調整卡片高度
在 home.dart
中為卡片新增 elevation:
值:
// TODO:調整卡片高度(103) elevation: 0.0, 複製程式碼
儲存你的專案。

現在你已經移除了卡片下的陰影。
讓我們更改登陸頁面元件的高度來補全它。
調整 NEXT 按鈕的高度
RaisedButton 的預設高度是 2。讓我們把它調高一點。
在 login.dart
中為 NEXT RaisedButton 新增 elevation:
值:
RaisedButton( child: Text('NEXT'), elevation: 8.0, // 新增程式碼 複製程式碼
單擊停止按鈕,然後單擊執行。你的登陸頁面看起來應該是這樣的:

關於高度(Elevation)的說明:
- 所有 Material Design 的平面(surface)和元件都擁有高度值。
- 一個平面末尾與另一個平面開始的分隔由平面的邊緣區分。
- 表面之間的高差可以使用暗淡的或明亮的背景或陰影來表示。
- 其它平面前的平面通常包含更重要的內容。
7. 新增形狀
Shrine 定義了八角形或矩形的元素,它具有酷炫的幾何風格。讓我們在主螢幕上的卡片以及登入螢幕上的文字欄位和按鈕中實現形狀樣式。
在登入螢幕上更改文字欄位的形狀
在 app.dart
中,匯入 special cut corners border 檔案:
import 'supplemental/cut_corners_border.dart'; 複製程式碼
還是在 app.dart
中,在文字欄位的修飾主題上新增一個帶有切角的形狀:
// TODO:修飾輸入內容(103) inputDecorationTheme: InputDecorationTheme( border: CutCornersBorder(), // 替換程式碼 ), 複製程式碼
在登入螢幕上更改按鈕形狀
在 login.dart
中,向 CANCEL 按鈕新增一個斜面矩形邊框:
FlatButton( child: Text('CANCEL'), shape: BeveledRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(7.0)), ), 複製程式碼
FlatButton 沒有可見的形狀,為什麼我們要新增邊框形狀?這樣觸控時,波紋動畫將繫結到相同的形狀。
現在給 NEXT 按鈕新增同樣的形狀:
RaisedButton( child: Text('NEXT'), elevation: 8.0, shape: BeveledRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(7.0)), ), 複製程式碼
關於形狀的說明:
- 使用形狀可以促進品牌的視覺表達。
- 形狀具有可調曲線和無角度拐角,曲線和邊角以及拐角總數。
- 元件的形狀不應該干擾其可用性!
單擊停止按鈕,然後單擊執行:

8. 修改佈局
接下來,讓我們更改佈局以顯示不同寬高比和大小的卡片,以便使每張卡片看起來都是不同的。
用 AsymmetricView 替換 GridView
我們已經為不對稱的佈局編寫了檔案。
在 home.dart
中,修改以下所有檔案:
import 'package:flutter/material.dart'; import 'model/products_repository.dart'; import 'model/product.dart'; import 'supplemental/asymmetric_view.dart'; class HomePage extends StatelessWidget { // TODO:為 Category 新增變數(104) @override Widget build(BuildContext context) { // TODO:返回一個 AsymmetricView(104) // TODO:傳遞 Category 變數給 AsymmetricView(104) return Scaffold( appBar: AppBar( brightness: Brightness.light, leading: IconButton( icon: Icon(Icons.menu), onPressed: () { print('Menu button'); }, ), title: Text('SHRINE'), actions: <Widget>[ IconButton( icon: Icon(Icons.search), onPressed: () { print('Search button'); }, ), IconButton( icon: Icon(Icons.tune), onPressed: () { print('Filter button'); }, ), ], ), body: AsymmetricView(products: ProductsRepository.loadProducts(Category.all)), ); } } 複製程式碼
儲存專案。

現在產品以編織圖案風格水平滾動。此外狀態列文字(頂部的時間和網路)現在為黑色。那是因為我們將 AppBar 的 brightness 改為了 light, brightness: Brightness.light
9. 嘗試另一個主題
顏色是詮釋品牌的有效方式,顏色的微小變化會對您的使用者體驗產生很大影響。為了測試這一點,讓我們看看如果品牌的配色方案完全不同時 Shrine 會是什麼樣子。
修改顏色
在 colors.dart
中,新增以下內容:
const kShrineAltDarkGrey = const Color(0xFF414149); const kShrineAltYellow = const Color(0xFFFFCF44); 複製程式碼
在 app.dart
中,按照以下內容修改 _buildShrineTheme()
和 _buildShrineTextTheme
方法:
ThemeData _buildShrineTheme() { final ThemeData base = ThemeData.dark(); return base.copyWith( accentColor: kShrineAltDarkGrey, primaryColor: kShrineAltDarkGrey, buttonColor: kShrineAltYellow, scaffoldBackgroundColor: kShrineAltDarkGrey, cardColor: kShrineAltDarkGrey, textSelectionColor: kShrinePink100, errorColor: kShrineErrorRed, textTheme: _buildShrineTextTheme(base.textTheme), primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme), accentTextTheme: _buildShrineTextTheme(base.accentTextTheme), primaryIconTheme: base.iconTheme.copyWith( color: kShrineAltYellow ), inputDecorationTheme: InputDecorationTheme( border: CutCornersBorder(), ), ); } TextTheme _buildShrineTextTheme(TextTheme base) { return base.copyWith( headline: base.headline.copyWith( fontWeight: FontWeight.w500, ), title: base.title.copyWith( fontSize: 18.0 ), caption: base.caption.copyWith( fontWeight: FontWeight.w400, fontSize: 14.0, ), ).apply( fontFamily: 'Rubik', displayColor: kShrineSurfaceWhite, bodyColor: kShrineSurfaceWhite, ); } 複製程式碼
在 login.dart
中,將鑽石標誌變成白色:
Image.asset( 'assets/diamond.png', color: kShrineBackgroundWhite, // 新增程式碼 ), 複製程式碼
還是在 login.dart
中,將兩個文字欄位的強調色覆蓋更改為黃色:
AccentColorOverride( color: kShrineAltYellow, // 修改的程式碼 child: TextField( controller: _usernameController, decoration: InputDecoration( labelText: 'Username', ), ), ), SizedBox(height: 12.0), AccentColorOverride( color: kShrineAltYellow, // 修改的程式碼 child: TextField( controller: _passwordController, decoration: const InputDecoration( labelText: 'Password', ), ), ), 複製程式碼
在 home.dart
中,修改 brightness 為 dark:
brightness: Brightness.dark, 複製程式碼
儲存專案。現在應該出現新的主題了。


結果非常不同!讓我們在轉到 104 教程之前還原這個顏色程式碼。
10. 總結
到目前為止,您已經建立了一個按照設計師設計規範設計的應用程式。
完整的 MDC-103 應用程式可在 104-starter_and_102-complete
分支中找到。
您可以針對該分支中的應用測試您的頁面版本。
下一步
你現在已經使用過了以下 MDC 元件:主題、排版、高度和形狀。你可以在 MDC-Flutter 庫中探索更多元件和子系統。
深入 supplemental
目錄中的檔案來了解我們是如何製作水平滾動的,非對稱的佈局網格的。
如果您的應用程式設計包含 MDC 庫中沒有的元件元素該怎麼辦?在 MDC-104: Material Design 高階元件 一文中我們將展示如何使用 MDC 庫建立自定義元件以實現特定外觀。
如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為掘金 上的英文分享文章。內容覆蓋 Android 、 iOS 、 前端 、 後端 、 區塊鏈 、 產品 、 設計 、 人工智慧 等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃 、官方微博、 知乎專欄 。