通常狀況下,咱們的Application都有獨特的特色,UI設計師會結合業務和品牌的特色,指定組件的視覺定製。包含主題色,圓角,邊框等各類樣式定製。canvas
咱們就須要使用 Theme 在應用程序中定製全局顏色和各類樣式。bash
當咱們不設置主題時,系統會生成默認主題。好比咱們最熟悉的primaryColor,默認顏色是Colors.blue,Brightness默認值Brightness.light.app
官方關於主題的介紹請點擊 使用主題共享顏色和字體樣式。less
全局設置主題就是在應用程序根MaterialApp定製ThemeData.ide
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Theme',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
複製代碼
咱們想要在某些特定的頁面,定製不同的主題,能夠局部設置Theme. 具體有兩種方式,分別是建立特有的ThemeData和擴展父主題。函數
若是咱們不想使用當初定製應用程序的主題,使用這種方式,能夠直接覆蓋原有的父主題。字體
提示,Theme是一個Widget,繼承了StatelessWidget.動畫
Theme(
data: ThemeData(
accentColor: Colors.yellow,
),
child: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
);
複製代碼
咱們只須要改變ThemeData的某一項,可使用 copyWith 擴展負主題。ui
Theme(
data: Theme.of(context).copyWith(accentColor: Colors.yellow),
child: FloatingActionButton(
onPressed: null,
child: Icon(Icons.add),
),
);
複製代碼
經過Theme.of(context)函數獲取已設置的主題。this
好比獲取primaryColor
Color primaryColor = Theme.of(context).primaryColor;
複製代碼
提示:文本太長,如需查找,使用 ctrl + f.
屬性 | 類型 | 描述 |
---|---|---|
brightness | Brightness | 有兩種能夠選擇,Brightness.light和Brightness.dark |
primarySwatch | MaterialColor | MaterialColor間接繼承了Color |
primaryColor | Color | 主題色 |
primaryColorBrightness | Brightness | 判斷primaryColor是Brightness.light,仍是Brightness.dark |
primaryColorLight | Color | primaryColor的較暗顏色 |
primaryColorDark | Color | primaryColor的較亮顏色 |
accentColor | Color | 文本、按鈕等前景色 |
accentColorBrightness | Brightness | accentColor的亮度,用於肯定放置在突出顏色頂部的文本和圖標的顏色(例如FloatingButton上的圖標) |
canvasColor | Color | MaterialType.canvas Material的默認顏色 |
scaffoldBackgroundColor | Color | Material默認顏色 |
bottomAppBarColor | Color | BottomAppBar的默認顏色 |
cardColor | Color | Material被用做Card時的顏色 |
dividerColor | Color | Dividers和PopupMenuDividers的顏色,也用於ListTiles中間,和DataTables的每行中間 |
focusColor | Color | |
hoverColor | Color | |
highlightColor | Color | 用於相似墨水噴濺動畫或指示菜單被選中的高亮顏色 |
splashColor | Color | 墨水噴濺的顏色 |
splashFactory | InteractiveInkFeatureFactory | 定義InkWall和InkResponse生成的墨水噴濺的外觀 |
selectedRowColor | Color | 選中行時的高亮顏色 |
unselectedWidgetColor | Color | 用於Widget處於非活動(但已啓用)狀態的顏色。 例如,未選中的複選框。 一般與accentColor造成對比 |
disabledColor | Color | 用於Widget無效的顏色,不管任何狀態。例如禁用複選框。 |
buttonColor | Color | Material中RaisedButtons使用的默認填充色。 |
buttonTheme | ButtonThemeData | 定義了按鈕等控件的默認配置,像RaisedButton和FlatButton |
toggleButtonsTheme | ToggleButtonsThemeData | 定義ToggleButtons控件的默認配置 |
secondaryHeaderColor | Color | 有選定行時PaginatedDataTable標題的顏色。 |
textSelectionColor | Color | 文本字段中選中文本的顏色,例如TextField。 |
cursorColor | Color | 光標顏色 |
textSelectionHandleColor | Color | 用於調整當前文本的哪一個部分的句柄顏色。 |
backgroundColor | Color | 做爲Scaffold基礎的Material默認顏色,典型Material應用或應用內頁面的背景顏色。 |
dialogBackgroundColor | Color | Dialog元素的背景色。 |
indicatorColor | Color | TabBar中選項選中的指示器顏色。 |
hintColor | Color | 用於提示文本或佔位符文本的顏色,例如在TextField中。 |
errorColor | Color | 用於輸入驗證錯誤的顏色,例如在TextField中。 |
toggleableActiveColor | Color | 用於突出顯示切換Widget(如Switch,Radio和Checkbox)的活動狀態的顏色。 |
fontFamily | String | 字體系列,如「Roboto」 |
textTheme | TextTheme | 文本默認主題 |
primaryTextTheme | TextTheme | 一個與主色對比的文本主題 |
accentTextTheme | TextTheme | 與突出顏色對照的文本主題。 |
inputDecorationTheme | InputDecorationTheme | InputDecorator,TextField和TextFormField的默認InputDecoration值基於此主題。 |
iconTheme | IconThemeData | 與卡片和畫布顏色造成對比的圖標主題。 |
primaryIconTheme | IconThemeData | 一個與主色對比的圖片主題。 |
accentIconTheme | IconThemeData | 與突出顏色對照的圖片主題。 |
sliderTheme | SliderThemeData | 用於渲染Slider的顏色和形狀。 |
tabBarTheme | TabBarTheme | TabBar的默認出題 |
tooltipTheme | TooltipThemeData | 提示Tooltip的默認主題 |
cardTheme | CardTheme | Card的默認主題 |
chipTheme | ChipThemeData | 用於渲染Chip的顏色和樣式。 |
platform | TargetPlatform | Widget須要適配的目標類型。 |
materialTapTargetSize | MaterialTapTargetSize | |
applyElevationOverlayColor | bool | |
pageTransitionsTheme | PageTransitionsTheme | |
appBarTheme | AppBarTheme | AppBar默認主題 |
bottomAppBarTheme | BottomAppBarTheme | BottomAppBar的默認主題 |
colorScheme | ColorScheme | |
dialogTheme | DialogTheme | Dialog的默認主題 |
floatingActionButtonTheme | FloatingActionButtonThemeData | FloatingActionButton的默認主題 |
typography | Typography | |
cupertinoOverrideTheme | CupertinoThemeData | |
snackBarTheme | SnackBarThemeData | SnackBar的默認主題 |
bottomSheetTheme | BottomSheetThemeData | |
popupMenuTheme | PopupMenuThemeData | |
bannerTheme | MaterialBannerThemeData | |
dividerTheme | DividerThemeData |
看源碼更容易理解
brightness ??= Brightness.light;
final bool isDark = brightness == Brightness.dark;
primarySwatch ??= Colors.blue;
primaryColor ??= isDark ? Colors.grey[900] : primarySwatch;
primaryColorBrightness ??= estimateBrightnessForColor(primaryColor);
primaryColorLight ??= isDark ? Colors.grey[500] : primarySwatch[100];
primaryColorDark ??= isDark ? Colors.black : primarySwatch[700];
final bool primaryIsDark = primaryColorBrightness == Brightness.dark;
toggleableActiveColor ??= isDark ? Colors.tealAccent[200] : (accentColor ?? primarySwatch[600]);
accentColor ??= isDark ? Colors.tealAccent[200] : primarySwatch[500];
accentColorBrightness ??= estimateBrightnessForColor(accentColor);
final bool accentIsDark = accentColorBrightness == Brightness.dark;
canvasColor ??= isDark ? Colors.grey[850] : Colors.grey[50];
scaffoldBackgroundColor ??= canvasColor;
bottomAppBarColor ??= isDark ? Colors.grey[800] : Colors.white;
cardColor ??= isDark ? Colors.grey[800] : Colors.white;
dividerColor ??= isDark ? const Color(0x1FFFFFFF) : const Color(0x1F000000);
// Create a ColorScheme that is backwards compatible as possible
// with the existing default ThemeData color values.
colorScheme ??= ColorScheme.fromSwatch(
primarySwatch: primarySwatch,
primaryColorDark: primaryColorDark,
accentColor: accentColor,
cardColor: cardColor,
backgroundColor: backgroundColor,
errorColor: errorColor,
brightness: brightness,
);
splashFactory ??= InkSplash.splashFactory;
selectedRowColor ??= Colors.grey[100];
unselectedWidgetColor ??= isDark ? Colors.white70 : Colors.black54;
// Spec does not specify a dark theme secondaryHeaderColor, this is a guess.
secondaryHeaderColor ??= isDark ? Colors.grey[700] : primarySwatch[50];
textSelectionColor ??= isDark ? accentColor : primarySwatch[200];
// TODO(sandrasandeep): change to color provided by Material Design team
cursorColor = cursorColor ?? const Color.fromRGBO(66, 133, 244, 1.0);
textSelectionHandleColor ??= isDark ? Colors.tealAccent[400] : primarySwatch[300];
backgroundColor ??= isDark ? Colors.grey[700] : primarySwatch[200];
dialogBackgroundColor ??= isDark ? Colors.grey[800] : Colors.white;
indicatorColor ??= accentColor == primaryColor ? Colors.white : accentColor;
hintColor ??= isDark ? const Color(0x80FFFFFF) : const Color(0x8A000000);
errorColor ??= Colors.red[700];
inputDecorationTheme ??= const InputDecorationTheme();
pageTransitionsTheme ??= const PageTransitionsTheme();
primaryIconTheme ??= primaryIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
accentIconTheme ??= accentIsDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black);
iconTheme ??= isDark ? const IconThemeData(color: Colors.white) : const IconThemeData(color: Colors.black87);
platform ??= defaultTargetPlatform;
typography ??= Typography(platform: platform);
final TextTheme defaultTextTheme = isDark ? typography.white : typography.black;
textTheme = defaultTextTheme.merge(textTheme);
final TextTheme defaultPrimaryTextTheme = primaryIsDark ? typography.white : typography.black;
primaryTextTheme = defaultPrimaryTextTheme.merge(primaryTextTheme);
final TextTheme defaultAccentTextTheme = accentIsDark ? typography.white : typography.black;
accentTextTheme = defaultAccentTextTheme.merge(accentTextTheme);
materialTapTargetSize ??= MaterialTapTargetSize.padded;
applyElevationOverlayColor ??= false;
if (fontFamily != null) {
textTheme = textTheme.apply(fontFamily: fontFamily);
primaryTextTheme = primaryTextTheme.apply(fontFamily: fontFamily);
accentTextTheme = accentTextTheme.apply(fontFamily: fontFamily);
}
// Used as the default color (fill color) for RaisedButtons. Computing the
// default for ButtonThemeData for the sake of backwards compatibility.
buttonColor ??= isDark ? primarySwatch[600] : Colors.grey[300];
focusColor ??= isDark ? Colors.white.withOpacity(0.12) : Colors.black.withOpacity(0.12);
hoverColor ??= isDark ? Colors.white.withOpacity(0.04) : Colors.black.withOpacity(0.04);
buttonTheme ??= ButtonThemeData(
colorScheme: colorScheme,
buttonColor: buttonColor,
disabledColor: disabledColor,
focusColor: focusColor,
hoverColor: hoverColor,
highlightColor: highlightColor,
splashColor: splashColor,
materialTapTargetSize: materialTapTargetSize,
);
toggleButtonsTheme ??= const ToggleButtonsThemeData();
disabledColor ??= isDark ? Colors.white38 : Colors.black38;
highlightColor ??= isDark ? _kDarkThemeHighlightColor : _kLightThemeHighlightColor;
splashColor ??= isDark ? _kDarkThemeSplashColor : _kLightThemeSplashColor;
sliderTheme ??= const SliderThemeData();
tabBarTheme ??= const TabBarTheme();
tooltipTheme ??= const TooltipThemeData();
appBarTheme ??= const AppBarTheme();
bottomAppBarTheme ??= const BottomAppBarTheme();
cardTheme ??= const CardTheme();
chipTheme ??= ChipThemeData.fromDefaults(
secondaryColor: primaryColor,
brightness: brightness,
labelStyle: textTheme.body2,
);
dialogTheme ??= const DialogTheme();
floatingActionButtonTheme ??= const FloatingActionButtonThemeData();
cupertinoOverrideTheme = cupertinoOverrideTheme?.noDefault();
snackBarTheme ??= const SnackBarThemeData();
bottomSheetTheme ??= const BottomSheetThemeData();
popupMenuTheme ??= const PopupMenuThemeData();
bannerTheme ??= const MaterialBannerThemeData();
dividerTheme ??= const DividerThemeData();
複製代碼