Flutter主題Theme的詳解(建立&使用&擷取)
為了在整個應用中共享顔色和字型樣式,我們可以使用主題。定義主題有兩種方式:全局主題或使用Theme來定義應用程式局部的顔色和字型樣式。事實上,全局主題隻是由應用程式根MaterialApp建立的Theme。
定義一個主題後,我們可以在我們自己的Widgets中使用它。另外,Flutter提供的Material Widgets将使用我們的主題為AppBars、Buttons、Checkboxes等設定背景顔色和字型樣式。
建立主題
可以通過配置ThemeData類輕松更改應用程式的主題。
ThemeData
ThemeData是Material Design Widget庫的主題資料,Material庫的Widget需要遵守相應的設計規範,而這些規範可自定義(部分),是以我們可以通過ThemeData來自定義應用主題,我們可以通過Theme.of方法來擷取目前的ThemeData。
ThemeData部分資料:
ThemeData({
Brightness brightness, //深色還是淺色
MaterialColor primarySwatch, //主題顔色樣本,見下面介紹
Color primaryColor, //主色,決定導航欄顔色
Color accentColor, //次級色,決定大多數Widget的顔色,如進度條、開關等。
Color cardColor, //卡片顔色
Color dividerColor, //分割線顔色
ButtonThemeData buttonTheme, //按鈕主題
Color cursorColor, //輸入框光标顔色
Color dialogBackgroundColor,//對話框背景顔色
String fontFamily, //文字字型
TextTheme textTheme,// 字型主題,包括标題、body等文字樣式
IconThemeData iconTheme, // Icon的預設樣式
TargetPlatform platform, //指定平台,應用特定平台控件風格
...
})
設定整個應用的主題
例如,為了在整個應用程式中共享包含顔色和字型樣式的主題,我們可以提供ThemeData給MaterialApp的構造函數。
示例:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'budaye',
theme: new ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.white,
accentColor: Colors.cyan[600],
),
home: new RandomWords(),
);
}}
局部主題
如果我們想在應用程式的一部分中覆寫應用程式的全局的主題,我們可以将要覆寫得部分封裝在一個Theme Widget中。
有兩種方法可以解決這個問題:建立特有的ThemeData或擴充父主題。
1. 建立特有的 ThemeData
如果我們不想繼承任何應用程式的顔色或字型樣式,我們可以通過new ThemeData()建立一個執行個體并将其傳遞給Theme Widget。
new Theme(
// Create a unique theme with "new ThemeData"
data: new ThemeData(
accentColor: Colors.yellow,
),
child: new FloatingActionButton(
onPressed: () {},
child: new Icon(Icons.add),
),
);
2. 擴充父主題
擴充父主題時無需覆寫所有的主題屬性,我們可以通過使用copyWith方法來實作。
new Theme(
// Find and Extend the parent theme using "copyWith". Please see the next
// section for more info on `Theme.of`.
data: Theme.of(context).copyWith(accentColor: Colors.yellow),
child: new FloatingActionButton(
onPressed: null,
child: new Icon(Icons.add),
),
);
使用主題
1. 應用主題的使用
應用主題的使用上面已經介紹了,這裡不做重複介紹了。
2. 局部主題的使用
在想要應用局部主題的widget外部,包裹Theme來實作:
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// backgroundColor: Colors.green, //設定标題欄的背景顔色
title: new Title(
child: new Text(
'這是一個标題',
),
color: Colors.white,
),
),
body: new Theme(
// Create a unique theme with "new ThemeData"
data: new ThemeData(
// accentColor: Colors.yellow,
),
child: new FloatingActionButton(
onPressed: () {},
child: new Icon(Icons.add),
),
),
);
}
}
3. 主題的擷取
現在我們已經定義了一個主題,我們可以在Widget的build方法中通過Theme.of(context)函數使用它。
Theme.of(context)将查找Widget樹并傳回樹中最近的Theme。如果我們的Widget之上有一個單獨的Theme定義,則傳回該值。如果不是,則傳回App主題。
new Container(
color: Theme.of(context).accentColor,
child: new Text(
'Text with a background color',
style: Theme.of(context).textTheme.title,
),
);