flutter 主题色彩管理组件 flex_color_scheme

news2025/1/11 22:55:13

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/

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

https://space.bilibili.com/389903587/channel/collectiondetail?sid=246709

本机环境

❯ 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 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/667681.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[RocketMQ] NameServer启动流程源码解析 (一)

文章目录 1.NameServer概述2.NamesrvStartup启动入口3.createNamesrvController创建NamesrvController3.1 创建NamesrvController 4.start启动NamesrvController4.1 初始化NettyServer4.1.1 创建NettyRemotingServer4.1.2 registerProcessor注册默认请求处理器4.1.3 启动定时任…

Google C++ Style文档及常用代码规范(一):命名约定、格式、注释

文章目录 Google C Style文档及常用代码规范(一):命名约定、格式、注释命名约定通用命名规则文件命名类型命名变量命名常量命名函数命名命名空间命名枚举命名宏命名命名规则的特例 格式注释注释风格文件注释类注释函数注释变量注释类数据成员…

flutter getx nested navigation 嵌套路由

flutter getx nested navigation 嵌套路由 视频 https://youtu.be/SXER4JVBFps 前言 嵌套路由可以用在如购物确认向导界面切换。 使用 getx 实现嵌套路由,需要如下步骤: 通过 Navigator 组件的 key 属性 用 Get.nestedKey(1) 进行标记 onGenerateRoute…

delmia msd学习

在默认打开的结构树中添加一个产品tworobts TwoRobots是新建的一个空产品,并将其插入到resoourceslist下面通过 然后创建一个工位的工作区域 插入机器人 把机器人放在工作区域中,即其子物体 先选要移动的对象,然后选移动到什么地方 Keep positions的意思…

栈的概念和结构以及实现

1. 栈 1.1栈的概念及结构 栈:一种特殊的线性表,其只允许在 固定的一端 进行 插入和删除 元素操作。 进行数据插入和删除 操作的一端称为 栈顶 ,另一端称为 栈底 。栈中的数据元素遵守 后进先出 LIFO (Last in First Out) 的原则。 压栈:栈的插入操作叫做…

【带你刷《剑指Offer》系列】【每天40分钟,跟我一起用50天刷完 (剑指Offer)】第一天

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录)   文章字体风格: 红色文字表示&#…

python:使用Scikit-image对单波段遥感影像进行形状特征提取(morphology)

作者:CSDN @ _养乐多_ 本文将介绍使用Scikit-image对单波段遥感影像做形状特征提取的方法和代码。包括:腐蚀(erosion),膨胀(dilation),开运算(opening),闭运算(closing),形态学梯度(morphological gradient),白帽变换(top hat),黑帽变换(black hat),形…

一、枚举类型——用EnumSet来代替标识

Set 是一种不允许有重复元素存在的集合。enum 要求每个内部成员都是唯一的,因此看起来很像 Set,但是由于无法添加或移除元素,它并不如 Set 那么好用。于是 EnumSet 被引入,用来配合 enum 的使用,以替代传统的基于 int …

计算机启动

按下主机上的 power 键后,第一个运行的软件是 BIOS,BIOS 全称叫 Base Input & Output System,即基本输入输出系统。 (8086的1MB内存) 地址 0~0x9FFFF 处是 DRAM,顶部的 0xF0000~0xFFFFF&am…

第一章 基础算法(一)—— 快排,归并与二分

文章目录 快排归并排序二分整数二分浮点数二分 快速排序练习题785. 快速排序786. 第k个数 归并排序练习题787. 归并排序788. 逆序对的数量 二分练习题789. 数的范围790. 数的三次方根 有些累了,把这两天做的笔记整理发出 快排 快排的思路: 确定分界点根…

Pandas-DataFrame常用基础知识点总结

注:以下知识点总结是将数据转为DataFrame格式数据的基础之上进行操作的 (首先需要做的是将数据转为DataFrame格式) DataFrame格式示例: import pandas as pd data {"code": [000008, 000009, 000021, 000027, 00003…

代码随想录二刷 day28 | 回溯 之 93.复原IP地址 78.子集 90.子集II

day28 93.复原IP地址判断子串是否合法 78.子集回溯三部曲 90.子集II 93.复原IP地址 题目链接 解题思路: 切割问题就可以使用回溯搜索法把所有可能性搜出来 回溯三部曲 递归参数 startIndex一定是需要的,因为不能重复分割,记录下一层递归分…

一种数据源切换的实践方案

随着业务的不断深入,我们会碰见很多关于数据源切换的业务场景,数据源切换也是当前最常用的分库后的分流策略方式之一,对于读写职责分离的数据库集群而言,我们在服务层面制定相应的接口与数据库交互的定制化开发,也就是…

云 cloud 高可用系统--在RDS上实现,从原理上不可能保证你100%不丢数据

我写这篇文字,实属无奈,在目前很多企业都依赖云的情况下,数据库的很多事情都是身不由己,发生问题,你查看日志,分析日志可能你连日志都不是全部的,并且想通过程序来过滤这个日志很多情况下都有限…

数据库系统概述——第六章 关系数据理论(知识点复习+练习题)

🌟博主:命运之光 🦄专栏:离散数学考前复习(知识点题) 🍓专栏:概率论期末速成(一套卷) 🐳专栏:数字电路考前复习 🦚专栏&am…

CMU 15-445 Project #2 - B+Tree(CHECKPOINT #1)

CHECKPOINT #1 一、题目链接二、准备工作三、部分实现1.查找操作2.插入操作3.删除操作 四、评测结果 一、题目链接 二、准备工作 见 CMU 15-445 Project #0 - C Primer 中的准备工作。 三、部分实现 对于B树的节点定义,通过节点类的命名 b_plus_tree_page 不难发现…

linux-centos7操作系统查看系统未挂载的磁盘,挂载磁盘

linux-centos7操作系统查看系统未挂载的磁盘,挂载磁盘 查看当前磁盘空间 根目录 / 下也只有44G,其他目录只有10几G,正式环境肯定不够用 df -h查看硬盘数量和分区情况 fdisk -l查看到/dev/vdb 有500多G了 将/dev/vdb在分出一个区使用 第一步:编辑分区。执行命令fdisk …

pr视频叠加,即原视频右上角添加另外一个视频方法,以及pr导出视频步骤

一、pr视频叠加,即原视频右上角添加另外一个视频方法 在使用pr制作视频时,我们希望在原视频的左上角或右上角同步播放另外一个视频,如下图所示: 具体方法为: 1、导入原视频,第一个放在v1位置,第…

Selenium编写自动化用例的8种技巧

在开始自动化时,您可能会遇到各种可能包含在自动化代码中的方法,技术,框架和工具。有时,与提供更好的灵活性或解决问题的更好方法相比,这种多功能性导致代码更加复杂。在编写自动化代码时,重要的是我们能够…

【序列dp】最长上升子序列(一)

文章目录 最长上升子序列-序列dp概览895 最长上升子序列-O(n^2)1017 怪盗基德的滑翔翼1014 登山482 合唱队形1012 友好城市 最长上升子序列-序列dp 什么是序列相关的 DP ?序列相关 DP,顾名思义,就是将动态规划算法用于数组或者字符串上&…