Flutter主題風格

在Flutter開發中,咱們能夠經過定義 Theme,複用顏色和字體樣式,從而讓整個app的設計看起來更一致。html

一. Theme主題的使用

Theme分爲:全局Theme和局部Themevue

主題有兩個做用:git

  • 設置了主題以後,某些Widget會自動使用主題的樣式(好比AppBar的顏色)
  • 將某些樣式放到主題中統一管理,在應用程序的其它地方直接引用

1.1. 全局Theme

全局Theme會影響整個app的顏色和字體樣式。github

使用起來很是簡單,只須要向MaterialApp構造器傳入 ThemeData 便可。web

  • 若是沒有設置Theme,Flutter將會使用預設的樣式。
  • 固然,咱們能夠對它進行定製。
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(),  );  } } 複製代碼
全局主題
全局主題

1.2. 局部Theme

若是某個具體的Widget不但願直接使用全局的Theme,而但願本身來定義,應該如何作呢?算法

  • 很是簡單,只須要在Widget的父節點包裹一下Theme便可

建立另一個新的頁面,頁面中使用新的主題:api

  • 在新的頁面的Scaffold外,包裹了一個Theme,而且設置data爲一個新的ThemeData
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(  ),  );  } } 複製代碼

1.3. Flutter中文網錯誤

可是這裏有一個注意事項:accentColor在這裏並不會被覆蓋。app

爲何不能覆蓋呢?https://github.com/material-components/material-components-flutter-codelabs/issues/106less

我摘抄一點官方人員的回覆:

image-20200325105126901
image-20200325105126901

其實官網文檔中以前也出現了相似的錯誤,好比Flutter中文網以前是翻譯官方文檔的

  • https://flutterchina.club/cookbook/design/themes/其中就有該錯誤
image-20200325103731257
image-20200325103731257

後來官網文檔中對這個問題進行了修正:

image-20200325103957271
image-20200325103957271

二. 暗黑Theme適配

2.1. darkTheme

目前不少應用程序都須要適配暗黑模式,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(),  );  } } 複製代碼
主題適配
主題適配

2.2. 開發中適配

在開發中,爲了能適配兩種主題(設置是更多的主題),咱們能夠封裝一個AppTheme

  • 1.公共的樣式抽取成常量
  • 2.封裝一個亮色主題
  • 3.封裝一個暗黑主題
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、數據結構與算法等等,也會更新一些本身的學習心得等,歡迎你們關注

公衆號
公衆號
相關文章
相關標籤/搜索