type
status
date
slug
summary
tags
category
icon
password

前言

最近在学习 Flutter 开发,其中主题切换是一个增强用户体验的重要方式,也是 Flutter 学习中不可忽略的一个主题。本文将详细介绍 Flutter 在主题切换方面的实现。

主要内容

这篇文章主要介绍以下几个模块的内容:
  • 为什么 App 需要支持更换主题
  • Flutter 如何设置主题
  • Flutter 如何在夜间和白天模式之间切换
  • Flutter 如何动态切换颜色主题
    • 如何使用 provider 实现主题的动态切换

为什么 App 需要支持更换主题

  • 提高用户体验: 不同用户有不同的审美偏好, 主题切换可以满足更多用户的视觉喜好。
  • 个性化体验:主题切换可以展现 App 的个性化特点,让用户自定义主题以个性化其使用体验。
  • 辅助可访问性:对于视力障碍用户,切换到高对比度的主题可以提升 App 的可访问性。

Flutter 如何设置主题

Flutter 中设置主题非常简单, 只需要配置主题的参数即可。如果不设置, Flutter 也会使用默认主题。,就像这样。
notion image
如果你不喜欢默认主题的颜色,只需要在 MaterialApp 中编辑 theme 即可更新主题。
notion image
如果想使用夜间模式,只需要增加 darkTheme: ThemeData.dark()
这样 app 会根据系统的设置自动变更主题模式。如果想要手动指定主题模式,可以在代码中设置 themeMode: ThemeMode.light。这样会强制制定 app 的主题模式为白天模式。

Material 3 如何设置

Material 3 的设置更简单一些,只需要指定使用 useMaterial3: true 即可。
💡
后续的所有示例代码都使用 Material3。
 
Material 3的允许用户从单个种子颜色设置整个应用程序的颜色主题。在你的主题构造器中设置配色方案种子参数,Flutter 会从这个条目中为你的应用中的每个小部件生成一个和谐的配色方案。 比如下图是 colorSchemeSeed: const Color.fromARGB(86, 80, 14, 171), 的配色方案:
 
 
notion image
notion image

Flutter 如何在夜间和白天模式之间切换

在应用程序中,白天模式和夜间模式是指应用程序的显示风格。白天模式通常使用明亮的颜色和高对比度,而夜间模式则使用深色背景和低对比度。
白天模式通常用于在明亮的环境下使用应用程序,因为明亮的颜色和高对比度可以帮助用户更好地查看内容。夜间模式通常用于在昏暗的环境下使用应用程序,因为深色背景和低对比度可以减少眼睛疲劳。
notion image
 
在 Flutter 中动态切换白天和夜间模式非常简单,只需要增加一个中间变量来存储主题的模式。
实现模式切换的步骤:
  1. 定义白天和夜间两套主题;
  1. 添加一个 ThemeMode 变量来保存当前主题模式;
  1. 通过设置该变量为 light/dark 来切换主题模式;
  1. 切换后界面会自动build以应用新的主题。
具体代码如下:
这段代码定义了一个简单的 Flutter 应用程序,有明暗两种主题。代码首先定义了一个 ThemeMode 变量 themeMode,并初始化为 ThemeMode.system。这意味着应用程序将使用系统的默认主题,通常是 Android 上的明亮主题和 iOS 上的暗黑主题。
接下来定义明暗两种主题。明亮主题使用 ThemeData 类来定义。useMaterial3 属性设置为 true 以使用新的 Material 3 设计语言。colorSchemeSeed 属性设置为特定颜色,该颜色将用作主题的基础色。
暗黑主题类似定义,只是 brightness 属性设置为 Brightness.dark
最后,使用 MaterialApp 小部件来创建应用程序。theme 属性设置为明亮主题,themeMode 属性设置为 themeMode 变量。这意味着应用程序将以明亮主题启动,但用户可以通过单击相应的按钮将主题更改为暗黑。
Scaffold 小部件用于创建应用程序的基本布局。appBar 属性用于创建应用栏,backgroundColor 属性设置为当前主题的 primary container 颜色。body 属性用于创建应用程序的主体,在本例中是一个简单的列表,其中包含两个按钮。
两个按钮用于更改主题。当用户单击 "light" 按钮时,themeMode 变量将设置为 ThemeMode.light,应用程序将切换到明亮主题。当用户单击 "dark" 按钮时,themeMode 变量将设置为 ThemeMode.dark,应用程序将切换到暗黑主题。

Flutter 如何动态切换颜色主题

如何设置颜色主题

对于 Flutter App 主题的颜色的配置,有两种方式:
  1. 使用 token 设置主题色
  1. 使用自定义配色方案

使用 Token 设置主题色

在 Flutter 的 Material Design 中,"token" 是一个跟设计系统相关的概念,特别是在 Google 的 "Material You" 系统中。在这个系统中,token 是用于定义应用外观和感觉的一组参数。这些参数可以包含颜色、字体、形状等各种元素,用于在应用中创建一致的视觉体验。
Token 是一种抽象的概念,可以被视为一个变量或者一个标识符,其表示了一种特定的视觉样式。例如,一个颜色 token 可以表示主题的主色,而一个字体 token 可以表示应用程序中的标题字体。 这样可以保证 App 中的视觉样式与 Material Design 的要求保持一致, 也使得不同页面和组件的样式协调统一。
在 Flutter 中,你可以通过 ThemeData 来设置这些 token。例如,你可以通过 ThemeData 的 primaryColor 和 accentColor 属性来设置你应用的主色和强调色。类似地,你也可以通过 textTheme 来设置应用中的文字样式。
对于 Material 3 来说,可以使用以下方法设置颜色的 Token,可以在整个 App 中使用相同的主题色与背景色,而不需要重复定义。

使用自定义配色方案

在 Flutter 中, 可以通过以下步骤自定义 Material 风格的色彩方案:
1、创建一个 colors. dart 文件, 在里面定义颜色变量, 比如:
2、在主题中引用这些自定义颜色:
3、将 colors.dart 导入要应用主题的页面, 并通过 Theme.of(context) 获取主题设置组件样式:
4、也可以创建多个主题, 在切换主题时传入不同的 ThemeData 对象:
5、定制主题中的其他样式, 如字体、形状、阴影等。
通过这种方式, 我们可以自由组合颜色、视觉效果, 而不需深入 Material 源码, 实现 Brand 化的自定义主题。
💡
一个简单生成配色的方法是使用 material Theme Builder,可以根据选定的颜色 token,自定义生成一整套配色方案。 https://m3.material.io/theme-builder#/custom
 

如何动态切换主题配色

notion image
 
实现 App 动态切换主题颜色的方法有很多, 今天我主要介绍一种比较推荐的方式——使用 Provider。
Provider 可以实现主题状态的集中管理, 使主题可以动态修改。
  1. 创建 ThemeProvider 类负责状态管理;
  1. root page 设置 ThemeProvider;
  1. 页面中通过 Consumer 获取实例;
  1. 调用设置方法修改主题配置;
  1. 主题变化触发界面更新。

1. 创建主题提供者

首先我们创建一个ThemeProvider类来保存主题状态:
这段代码实现了一个 ThemeProvider, 它能够动态修改 App 的明暗两种主题。

2. 提供ThemeProvider

然后在 root page 提供这个 ThemeProvider:
这样实现有以下的优点:
  1. 在 MaterialApp 中, 通过 Consumer 获取 ThemeProvider 的实例。
  1. lightTheme和darkTheme中的色彩方案(colorScheme)直接引用了ThemeProvider中的lightScheme和darkScheme。
  1. 主题模式(themeMode)也是直接引用ThemeProvider的themeMode状态。
  1. 当ThemeProvider中的状态发生变化时,通过notifyListeners会触发Consumer的重新build,来动态切换主题。
  1. 在首页或其他页面,可以通过context获取ThemeProvider实例,调用其设置方法来更改主题模式和主题色彩。
  1. 这样通过provider把主题数据和状态抽取出来,在UI层简单重用,实现了低耦合的动态主题切换。
  1. ThemeProvider负责主题状态管理,UI层负责显示,二者职责分离,符合设计原则。

3. 获取ThemeProvider

在需要的页面获取provider实例:

4. 更改主题

调用 setLightScheme 和 setDarkScheme 更改主题色:
这样就可以通过provider在不同页面共享和修改主题配置了。利用Provider进行主题管理,可以避免重复代码,提供了响应式的主题配置。这是Flutter中实现动态主题的灵活简洁的方式。
💡
想要使用 provider 需要先添加 provider 依赖,具体代码如下,先在 `pubspec.yaml` 文件 `dev_dependencies` 部分添加 `provider: ^6.0.5`:

总结

Flutter 通过主题系统提供了强大的主题定制功能。我们可以通过多种方式自由切换主题, 以丰富应用体验和可访问性。掌握 Flutter 的主题机制是开发高质量 App 的重要一环。
以上对 Flutter 主题切换的实现做了全面介绍。如还有疑问,欢迎留言讨论。
比如主题按钮可以调用themeProvider的setter来切换主题模式,其他组件可以通过Provider获取themeProvider实例来修改样式。

参考链接

  1. https://m3.material.io/theme-builder#/custom
  1. https://juejin.cn/post/7078583859536723975
Flutter Markdown - How to use markdown in Flutter用 iPhone 备忘录 3 分钟创建个人网站
Gusibi
Gusibi
后端开发,擅长使用 Python 和 Golang,现在面向AI编程。热爱探索新互联网产品,曾写过小程序。正在学习 Flutter,热衷于技术的探索与进步。
公告
type
status
date
slug
summary
tags
category
icon
password
🎉欢迎访问🎉
-- 感谢您的支持 ---
👏欢迎更新体验👏
🤺
关于我

一些工具