Flutter Theme應用主題共享顏色和字體樣式

前言

通常狀況下,咱們的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擴展父主題函數

建立特有的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;
複製代碼

ThemeData的主要屬性及默認值

提示:文本太長,如需查找,使用 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

ThemeData構造器源碼

看源碼更容易理解

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();
複製代碼
相關文章
相關標籤/搜索