flutter 主题色彩管理组件 flex_color_scheme
前言
原文 https://ducafecat.com/blog/flutter-flex-color-scheme
平时我们做样式适配关心几个方面:
- 设计稿颜色
- 标记尺寸大小、比例
- 全局修改为主
- 快速可修改
今天将会介绍一个快速调整主题色彩样式的三方组件 flex_color_scheme
https://pub-web.flutter-io.cn/packages/flex_color_scheme
这个组件已经支持了 flutter 3.10 和 Material 3
参考
Flex color scheme
https://pub-web.flutter-io.cn/packages/flex_color_scheme
https://docs.flexcolorscheme.com/
https://rydmike.com/flexcolorscheme/themesplayground-v7-1/
Material 3
https://m3.material.io/theme-builder
https://space.bilibili.com/389903587/channel/collectiondetail...
本机环境
❯ flutter --version
Flutter 3.10.5 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 796c8ef792 (2 天前) • 2023-06-13 15:51:02 -0700
Engine • revision 45f6e00911
Tools • Dart 3.0.5 • DevTools 2.23.1
步骤
第一步:配置依赖
pubspec.yaml
dependencies:
flutter:
sdk: flutter
...
flex_color_scheme: ^7.1.2
第二步:打开样式定制器
https://rydmike.com/flexcolorscheme/themesplayground-v7-1/
第三步:复制样式代码
lib/main.dart
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
// Theme config for FlexColorScheme version 7.1.x. Make sure you use
// same or higher package version, but still same major version. If you
// use a lower package version, some properties may not be supported.
// In that case remove them after copying this theme to your app.
theme: FlexThemeData.light(
colors: const FlexSchemeColor(
primary: Color(0xff065808),
primaryContainer: Color(0xff9ee29f),
secondary: Color(0xff365b37),
secondaryContainer: Color(0xffaebdaf),
tertiary: Color(0xff2c7e2e),
tertiaryContainer: Color(0xffb8e6b9),
appBarColor: Color(0xffb8e6b9),
error: Color(0xffb00020),
),
surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
blendLevel: 7,
appBarStyle: FlexAppBarStyle.material,
appBarOpacity: 0.87,
transparentStatusBar: false,
appBarElevation: 12.5,
subThemesData: const FlexSubThemesData(
useTextTheme: true,
useM2StyleDividerInM3: true,
tabBarIndicatorWeight: 5,
tabBarIndicatorTopRadius: 6,
),
keyColors: const FlexKeyColors(
useSecondary: true,
useTertiary: true,
),
visualDensity: FlexColorScheme.comfortablePlatformDensity,
useMaterial3: true,
swapLegacyOnMaterial3: true,
// To use the Playground font, add GoogleFonts package and uncomment
// fontFamily: GoogleFonts.notoSans().fontFamily,
),
darkTheme: FlexThemeData.dark(
colors: const FlexSchemeColor(
primary: Color(0xff629f80),
primaryContainer: Color(0xff274033),
secondary: Color(0xff81b39a),
secondaryContainer: Color(0xff4d6b5c),
tertiary: Color(0xff88c5a6),
tertiaryContainer: Color(0xff356c50),
appBarColor: Color(0xff356c50),
error: Color(0xffcf6679),
),
surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
blendLevel: 13,
transparentStatusBar: false,
subThemesData: const FlexSubThemesData(
useTextTheme: true,
useM2StyleDividerInM3: true,
tabBarIndicatorWeight: 5,
tabBarIndicatorTopRadius: 6,
),
keyColors: const FlexKeyColors(
useSecondary: true,
useTertiary: true,
),
visualDensity: FlexColorScheme.comfortablePlatformDensity,
useMaterial3: true,
swapLegacyOnMaterial3: true,
// To use the Playground font, add GoogleFonts package and uncomment
// fontFamily: GoogleFonts.notoSans().fontFamily,
),
// If you do not have a themeMode switch, uncomment this line
// to let the device system mode control the theme mode:
themeMode: ThemeMode.system,
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
运行
通过 FlexSchemeColor 自定义颜色
const FlexSchemeData _myFlexScheme = FlexSchemeData(
name: 'Midnight blue',
description: 'Midnight blue theme, custom definition of all colors',
light: FlexSchemeColor(
primary: Color(0xFF00296B),
primaryContainer: Color(0xFFA0C2ED),
secondary: Color(0xFFD26900),
secondaryContainer: Color(0xFFFFD270),
tertiary: Color(0xFF5C5C95),
tertiaryContainer: Color(0xFFC8DBF8),
),
dark: FlexSchemeColor(
primary: Color(0xFFB1CFF5),
primaryContainer: Color(0xFF3873BA),
secondary: Color(0xFFFFD270),
secondaryContainer: Color(0xFFD26900),
tertiary: Color(0xFFC9CBFC),
tertiaryContainer: Color(0xFF535393),
),
);
FlexThemeData 是对 ThemeData 扩展
///
/// However, Dart does not yet support such extensions, see:
/// https://github.com/dart-lang/language/issues/723
extension FlexThemeData on ThemeData {
/// Returns a [ThemeData] object defined by factory [FlexColorScheme.light]
/// and its [FlexColorScheme.toTheme] method.
static ThemeData light({
/// The [FlexSchemeColor] that will be used to create the light
/// [FlexColorScheme].
///
/// You can use predefined [FlexSchemeColor] values from [FlexColor] or
/// [FlexColor.schemes] map or define your own colors with
/// [FlexSchemeColor] or [FlexSchemeColor.from].
///
/// For using built-in color schemes, the convenience shortcut to select
/// it with the [scheme] property is recommended and leaving [colors]
/// undefined. If both are specified the scheme colors defined by [colors]
/// are used. If both are null then [scheme] defaults to
/// [FlexScheme.material], thus defining the resulting scheme.
final FlexSchemeColor? colors,
FlexThemeData.light 返回的还是 ThemeData ,所以你可以加入自己的内容。
加入自定义样式定义
// Theme config for FlexColorScheme version 7.1.x. Make sure you use
// same or higher package version, but still same major version. If you
// use a lower package version, some properties may not be supported.
// In that case remove them after copying this theme to your app.
theme: FlexThemeData.light(
colors: const FlexSchemeColor(
primary: Color(0xff065808),
primaryContainer: Color(0xff9ee29f),
secondary: Color(0xff365b37),
secondaryContainer: Color(0xffaebdaf),
tertiary: Color(0xff2c7e2e),
tertiaryContainer: Color(0xffb8e6b9),
appBarColor: Color(0xffb8e6b9),
error: Color(0xffb00020),
),
surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
blendLevel: 7,
appBarStyle: FlexAppBarStyle.material,
appBarOpacity: 0.87,
transparentStatusBar: false,
appBarElevation: 12.5,
subThemesData: const FlexSubThemesData(
useTextTheme: true,
useM2StyleDividerInM3: true,
tabBarIndicatorWeight: 5,
tabBarIndicatorTopRadius: 6,
),
keyColors: const FlexKeyColors(
useSecondary: true,
useTertiary: true,
),
visualDensity: FlexColorScheme.comfortablePlatformDensity,
useMaterial3: true,
swapLegacyOnMaterial3: true,
// To use the Playground font, add GoogleFonts package and uncomment
// fontFamily: GoogleFonts.notoSans().fontFamily,
).copyWith(
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24),
),
),
),
通过 copyWith 的方式
FlexSubThemesData 子主题重写
/// Activate using FlexColorScheme opinionated component sub-themes by
/// passing in a default `FlexSubThemesData()`.
///
/// To further configure the sub-themes, change the simple flat value
/// properties as desired in `FlexSubThemesData()`.
///
/// By default [FlexThemeData.light], [FlexThemeData.dark] and
/// [FlexColorScheme.toTheme], do as little as they need to just
/// provide a consistent Material 2 color schemed theme. The additions they
/// do are described in [FlexColorScheme.toTheme].
///
/// The original purpose of the opinionated sub-themes was to make it easy
/// to add themed corner radius to all Widgets that support it, and to
/// provide a consistent look on all buttons, including [ToggleButtons].
///
/// Therefore the sub themes are a convenient way to opt-in on customized
/// corner radius on Widgets using above themes. By opting in you can set
/// corner radius for all covered Widgets to same corner radius in one go.
/// There are also properties to override the global default for each widget
/// to set different rounding per widget if so desired.
///
/// By default, if a `defaultRadius` is not specified, each widgets corner
/// radius and some other styling take inspiration from the Material 3 (M3)
/// specification https://m3.material.io/ and uses its specifications as
/// defaults when it is possible to do so in Flutter SDK theming when using
/// Material2 mode and via defaults also in Material 3 mode.
///
/// Starting from version 5, by opting in via a default [subThemesData] you
/// get an extensive set of widget component sub themes applied.
/// They can be customized via the [subThemesData] property, that has
/// quick and flat sub theme configuration values in the data class
/// [FlexSubThemesData].
///
/// Customizable sub-themes are available for:
///
/// * [AppBarTheme] for [AppBar] via [FlexSubThemes.appBarTheme].
/// * [BottomAppBarTheme] for [BottomAppBar] via
/// [FlexSubThemes.bottomAppBarTheme].
/// * [BottomNavigationBarThemeData] for [BottomNavigationBar] via
/// [FlexSubThemes.bottomNavigationBar].
/// * [BottomSheetThemeData] for [BottomSheet] via
/// [FlexSubThemes.bottomSheetTheme].
/// * [ButtonThemeData] for old deprecated buttons, via
/// [FlexSubThemes.buttonTheme].
/// * [CardTheme] for [Card] via [FlexSubThemes.cardTheme].
/// * [CheckboxThemeData] for [Checkbox] via [FlexSubThemes.checkboxTheme].
/// * [ChipThemeData] for [Chip] via [FlexSubThemes.chipTheme].
/// * [DatePickerThemeData] for [DatePicker] via
/// [FlexSubThemes.datePickerTheme].
/// * [DialogTheme] for [Dialog] via [FlexSubThemes.dialogTheme].
/// * [DrawerThemeData] for [Drawer] via [FlexSubThemes.drawerTheme].
/// * [DropdownMenuThemeData] for [DropDownMenu] via
/// [FlexSubThemes.dropdownMenuTheme].
/// * [ElevatedButtonThemeData] for [ElevatedButton] via
/// [FlexSubThemes.elevatedButtonTheme].
/// * [FilledButtonThemeData] for [FilledButton] via
/// [FlexSubThemes.filledButtonTheme].
/// * [FloatingActionButtonThemeData] for [FloatingActionButton] via
/// [FlexSubThemes.floatingActionButtonTheme].
/// * [IconButtonThemeData] for [IconButton] via
/// [FlexSubThemes.iconButtonTheme].
/// * [InputDecorationTheme] for [InputDecoration] via
/// [FlexSubThemes.inputDecorationTheme].
/// * [MenuBarThemeData] for [MenuBar] via [FlexSubThemes.menuBarTheme].
/// * [MenuButtonThemeData] for [MenuButton] via
/// [FlexSubThemes.menuButtonTheme].
/// * [MenuThemeData] for [MenuBar], [MenuAnchor] and [DropDownMenu] via
/// [FlexSubThemes.menuTheme].
/// * [ListTileThemeData] for [ListTile] via
/// [FlexSubThemes.listTileTheme].
/// * [NavigationBarThemeData] for [NavigationBar] via
/// [FlexSubThemes.navigationBarTheme].
/// * [NavigationDrawerThemeData] for [NavigationDrawer] via
/// [FlexSubThemes.navigationDrawerTheme].
/// * [NavigationRailThemeData] for [NavigationRail] via
/// [FlexSubThemes.navigationRailTheme].
/// * [OutlinedButtonThemeData] for [OutlinedButton] via
/// [FlexSubThemes.outlinedButtonTheme].
/// * [PopupMenuThemeData] for [PopupMenuButton] via
/// [FlexSubThemes.popupMenuTheme].
/// * [RadioThemeData] for [Radio] via [FlexSubThemes.radioTheme].
/// * [SliderThemeData] for [Slider] via [FlexSubThemes.sliderTheme].
/// * [SnackBarThemeData] for [SnackBar] via [FlexSubThemes.snackBarTheme].
/// * [SwitchThemeData] for [Switch] via [FlexSubThemes.switchTheme].
/// * [TabBarTheme] for [TabBar] via [FlexSubThemes.tabBarTheme].
/// * [TextButtonThemeData] for [TextButton] via
/// [FlexSubThemes.textButtonTheme].
/// * [TimePickerThemeData] for [TimePickerDialog] via
/// [FlexSubThemes.timePickerTheme].
/// * [ToggleButtonsThemeData] for [ToggleButtons] via
/// [FlexSubThemes.toggleButtonsTheme].
/// * [TooltipThemeData] for [Tooltip] via [FlexSubThemes.tooltipTheme].
///
/// Defaults to null, resulting in FlexColorScheme not using any extra
/// sub-theming in addition to those described in [FlexColorScheme.toTheme].
final FlexSubThemesData? subThemesData,
subThemesData 中罗列了常见的样式属性
代码
https://github.com/ducafecat/flutter_develop_tips/tree/main/flutter_application_flex_color_scheme
小结
flex_color_scheme 是一个快速的样式设置工具,还修复了 flutter sdk 中的一些组件颜色不到位的缺陷,赶快用上吧。
感谢阅读本文
如果我有什么错?请在评论中让我知道。我很乐意改进。
© 猫哥
ducafecat.com
end
本文由mdnice多平台发布