flutter 主题色调治理组件 flex_color_scheme

<img src="https://ducafecat.oss-cn-beijing.aliyuncs.com/podcast/2023/06/e2574aa65a9d0d525f8db6a87aacd934.jpeg" style="width:90%;" />

前言

原文 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

<img src="https://ducafecat.oss-cn-beijing.aliyuncs.com/podcast/2023/06/63bba7baf6445173a4be68350b853244.png" style="width:80%;" />

<img src="https://ducafecat.oss-cn-beijing.aliyuncs.com/podcast/2023/06/0461a5e64aa4f6cf73c1e4bf9b7e1b5a.png" style="width:80%;" />

参考

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/

https://m3.material.io/theme-builder

https://space.bilibili.com/389903587/channel/collectiondetail...

本机环境

❯ flutter --versionFlutter 3.10.5 • channel stable • https://github.com/flutter/flutter.gitFramework • revision 796c8ef792 (2 天前) • 2023-06-13 15:51:02 -0700Engine • revision 45f6e00911Tools • 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/

<img src="https://ducafecat.oss-cn-beijing.aliyuncs.com/podcast/2023/06/0ed2203ab90460b45937a70b886cb629.png" style="width:80%;" />

第三步:复制款式代码

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'),    );  }

运行

<img src="https://ducafecat.oss-cn-beijing.aliyuncs.com/podcast/2023/06/bc737d0ecd814c1e18467d32cc2817c9.png" style="width:30%;" />

通过 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/723extension 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 的形式

<img src="https://ducafecat.oss-cn-beijing.aliyuncs.com/podcast/2023/06/b98d330c9eae161c42ad427ea0e66617.png" style="width:33%;" />

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 中列举了常见的款式属性

<img src="https://ducafecat.oss-cn-beijing.aliyuncs.com/podcast/2023/06/7ad50affde6088c883bddf3608e926c1.png" style="width:60%;" />

代码

https://github.com/ducafecat/flutter_develop_tips/tree/main/flutter_application_flex_color_scheme

小结

flex_color_scheme 是一个疾速的款式设置工具,还修复了 flutter sdk 中的一些组件色彩不到位的缺点,赶快用上吧。

感激浏览本文

如果我有什么错?请在评论中让我晓得。我很乐意改良。


© 猫哥
ducafecat.com

end

本文由mdnice多平台公布