在Flutter開發中,咱們能夠經過定義
Theme
,複用顏色和字體樣式,從而讓整個app的設計看起來更一致。html
Theme分爲:全局Theme和局部Themevue
主題有兩個做用:git
設置了主題以後,某些Widget會自動使用主題的樣式(好比AppBar的顏色) 將某些樣式放到主題中統一管理,在應用程序的其它地方直接引用
全局Theme會影響整個app的顏色和字體樣式。github
使用起來很是簡單,只須要向MaterialApp構造器傳入 ThemeData
便可。web
class MyApp extends StatelessWidget {
// This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( // 1.亮度: light-dark brightness: Brightness.light, // 2.primarySwatch: primaryColor/accentColor的結合體 primarySwatch: Colors.red, // 3.主要顏色: 導航/底部TabBar primaryColor: Colors.pink, // 4.次要顏色: FloatingActionButton/按鈕顏色 accentColor: Colors.orange, // 5.卡片主題 cardTheme: CardTheme( color: Colors.greenAccent, elevation: 10, shape: Border.all(width: 3, color: Colors.red), margin: EdgeInsets.all(10) ), // 6.按鈕主題 buttonTheme: ButtonThemeData( minWidth: 0, height: 25 ), // 7.文本主題 textTheme: TextTheme( title: TextStyle(fontSize: 30, color: Colors.blue), display1: TextStyle(fontSize: 10), ) ), home: HYHomePage(), ); } } 複製代碼
若是某個具體的Widget不但願直接使用全局的Theme,而但願本身來定義,應該如何作呢?算法
建立另一個新的頁面,頁面中使用新的主題:api
class HYSecondPage extends StatelessWidget {
@override Widget build(BuildContext context) { return Theme( data: ThemeData(), child: Scaffold( ), ); } } 複製代碼
可是,咱們不少時候並非想徹底使用一個新的主題,並且在以前的主題基礎之上進行修改:數據結構
class HYSecondPage extends StatelessWidget {
@override Widget build(BuildContext context) { return Theme( data: Theme.of(context).copyWith( primaryColor: Colors.greenAccent ), child: Scaffold( ), ); } } 複製代碼
可是這裏有一個注意事項:accentColor在這裏並不會被覆蓋。app
爲何不能覆蓋呢?https://github.com/material-components/material-components-flutter-codelabs/issues/106less
我摘抄一點官方人員的回覆:
其實官網文檔中以前也出現了相似的錯誤,好比Flutter中文網以前是翻譯官方文檔的
後來官網文檔中對這個問題進行了修正:
目前不少應用程序都須要適配暗黑模式,Flutter中如何作到暗黑模式的適配呢?
事實上,MaterialApp中有theme和dartTheme兩個參數:
class MyApp extends StatelessWidget {
// This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData.light(), darkTheme: ThemeData.dark(), home: HYHomePage(), ); } } 複製代碼
在開發中,爲了能適配兩種主題(設置是更多的主題),咱們能夠封裝一個AppTheme
import 'package:flutter/material.dart';
class AppTheme { // 1.抽取相同的樣式 static const double _titleFontSize = 20; // 2.亮色主題 static final ThemeData lightTheme = ThemeData( primarySwatch: Colors.pink, primaryTextTheme: TextTheme( title: TextStyle( color: Colors.yellow, fontSize: _titleFontSize ) ), textTheme: TextTheme( body1: TextStyle(color: Colors.red) ) ); // 3.暗黑主題 static final ThemeData darkTheme = ThemeData( primaryColor: Colors.grey, primaryTextTheme: TextTheme( title: TextStyle( color: Colors.white, fontSize: _titleFontSize ) ), textTheme: TextTheme( title: TextStyle(color: Colors.white), body1: TextStyle(color: Colors.white70) ) ); } 複製代碼
在MaterialApp中,能夠決定使用哪個主題:
class MyApp extends StatelessWidget {
// This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: AppTheme.lightTheme, darkTheme: AppTheme.darkTheme, home: HYHomePage(), ); } } 複製代碼
備註:全部內容首發於公衆號,以後除了Flutter也會更新其餘技術文章,TypeScript、React、Node、uniapp、mpvue、數據結構與算法等等,也會更新一些本身的學習心得等,歡迎你們關注