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();
复制代码
相关文章
相关标签/搜索