为 Flutter 应用设置主题:ThemeData 和 ColorScheme 指南

news/2024/5/20 10:06:02

在媒体和其他来源中有许多关于这个主题的文章,那么这篇文章的必要性是什么?

在本文中,我计划仅关注 ThemeData 小部件的关键点以及我的开发经验中最常用的参数,并且您将获得有关每个参数如何对您的应用程序执行操作的简要说明。

你好奇吗?继续阅读🤗。

使用 ThemeData 的主要好处

  • 保持统一的外观: 定义一个单一的 ThemeData 对象,该对象封装了应用程序的调色板、字体、形状和其他视觉元素。在所有屏幕上一致应用该主题,确保品牌识别的一致性和可识别性。
  • 为不同的主题设计不同的版本: 为浅色和深色模式、应用分区或用户首选项定义多个 ThemeData 对象。
  • 只需定义一次主题,即可在任何地方使用它们: 无需手动设置单个小组件的视觉样式,而是在应用中应用适当的 ThemeData 小组件。这减少了代码重复并简化了维护。
  • 集中控制和更新:ThemeData 对象进行更改,这些更改会自动传播到整个应用,从而确保一致性并减少重复编辑的需要。
  • 创建无障碍变体: 为有特定无障碍需求的用户建立单独的主题数据对象,例如为视觉障碍用户建立高对比度主题。

现在你已经熟悉了 ThemeData 对你的帮助,那么如何在你的应用程序中实现它呢?😊

这是一个在 Flutter 应用程序中实现深色和浅色主题的基本主题的小指南。

创建全局类

第一步是创建一个全局类,用于在应用程序中管理 ThemeData。该类包含一个方法,用于使用 ColorSheme 创建不同的 ThemeData 实例。

class GlobalThemData {static ThemeData themeData(ColorScheme colorScheme, Color focusColor) {return ThemeData(colorScheme: colorScheme, focusColor: focusColor);}
}

focusColor : 该颜色用于 TextFields 和 TextFormField 等 widget,以指示该 widget 是否有主焦点。

ColorSheme :基于 Material 规范的一组 30 种颜色,可用于配置大多数组件的颜色属性。

我们可以在本文后面更详细地讨论 ColorSheme

现在,我们可以创建更多可直接从 GlobalThemData 类访问的公有变量。

lightColorScheme:持有浅色主题的 ColorSheme

darkColorScheme:持有暗色主题的 ColorSheme

lightThemeData:持有浅色主题的 ThemeData

darkThemeData:持有深色主题的 ThemeData

class GlobalThemData {static final Color _lightFocusColor = Colors.black.withOpacity(0.12);static final Color _darkFocusColor = Colors.white.withOpacity(0.12);static ThemeData lightThemeData = themeData(lightColorScheme, _lightFocusColor);static ThemeData darkThemeData = themeData(darkColorScheme, _darkFocusColor);static ThemeData themeData(ColorScheme colorScheme, Color focusColor) {return ThemeData(colorScheme: colorScheme, focusColor: focusColor);}static const ColorScheme lightColorScheme = ColorScheme();static const ColorScheme darkColorScheme = ColorScheme();
}

如果您和我一起编码,您可能会在 ColorSheme() 上收到必需的参数错误警告。

我们可以在下一步中解决这个问题。

ColorSheme

ColorSheme 中的颜色是成对的;第一个是颜色本身,第二个是可用于该颜色的颜色,如文本和其他元素。

这 10 种颜色对于为 Flutter ThemData 创建 ColorSheme 是必需的,每种颜色的值都是可选的。

  • primary:这是应用程序中最常用的颜色
  • onPrimary:此颜色用于为原色之上的元素(例如文本、图标等)着色。
  • secondary:这定义了一种辅助颜色,通常用于不太显眼的元素,如滤镜芯片、切换按钮或背景元素,这些元素需要从主色中脱颖而出,但又不能喧宾夺主。
  • onSecondary:该颜色用于为次要颜色上的元素着色。
  • error:这是用于错误消息或警报的颜色,例如闪烁的红灯表示问题。
  • onError:这是与 error 颜色相得益彰的文本颜色,例如红色标志上的白色文本,便于阅读。
  • background:整个应用程序的主要背景色。将其视为放置所有其他 UI 元素的画布。
  • onBackground:该颜色用于为背景色上的元素着色。
  • surface:用作卡片、工作表、对话框等高级 UI 元素的基色。

因此,我们可以按如下方式设置我们的 lightColorScheme and darkColorScheme 变量。

static const ColorScheme lightColorScheme = ColorScheme(primary: Color(0xFFB93C5D),onPrimary: Colors.black,secondary: Color(0xFFEFF3F3),onSecondary: Color(0xFF322942),error: Colors.redAccent,onError: Colors.white,background: Color(0xFFE6EBEB),onBackground: Colors.white,surface: Color(0xFFFAFBFB),onSurface: Color(0xFF241E30),brightness: Brightness.light,);
static const ColorScheme darkColorScheme = ColorScheme(primary: Color(0xFFFF8383),secondary: Color(0xFF4D1F7C),background: Color(0xFF241E30),surface: Color(0xFF1F1929),onBackground: Color(0x0DFFFFFF),error: Colors.redAccent,onError: Colors.white,onPrimary: Colors.white,onSecondary: Colors.white,onSurface: Colors.white,brightness: Brightness.dark,);

现在,我们为浅色和深色主题设置了一个 ColorScheme,那么如何在主题数据中使用它呢?

创建 ThemeData

我们需要修改 GlobalThemeData 中的 themeData 方法,为 ThemeData 创建一个合适的值 ColourScheme,并传递给它。

static ThemeData themeData(ColorScheme colorScheme, Color focusColor) {return ThemeData(colorScheme: colorScheme,canvasColor: colorScheme.background,scaffoldBackgroundColor: colorScheme.background,highlightColor: Colors.transparent,focusColor: focusColor);}
  • canvasColor: 这是整个屏幕或应用程序窗口的背景色。它定义了所有其他 UI 元素的基色。
  • scaffoldBackgroundColor: 这具体定义了脚手架本身的背景颜色,包括应用栏、正文内容区域和底部导航栏(如果存在)。
  • highlightColor: 该属性定义了用户点击并按住 Widget 时短暂显示的颜色。它为用户提供了交互已注册的视觉反馈。
  • focusColor:该属性定义了用于直观显示当前哪个元素具有焦点的颜色,这意味着该元素将接收键盘输入。这对于突出显示当前活动元素,吸引用户注意非常有用。

这些只是示例,还有许多其他选项 ThemeData 可供您探索。

因此,我们最终的 GlobalThemeData 类应该是这样的:

class GlobalThemData {static final Color _lightFocusColor = Colors.black.withOpacity(0.12);static final Color _darkFocusColor = Colors.white.withOpacity(0.12);static ThemeData lightThemeData =themeData(lightColorScheme, _lightFocusColor);static ThemeData darkThemeData = themeData(darkColorScheme, _darkFocusColor);static ThemeData themeData(ColorScheme colorScheme, Color focusColor) {return ThemeData(colorScheme: colorScheme,canvasColor: colorScheme.background,scaffoldBackgroundColor: colorScheme.background,highlightColor: Colors.transparent,focusColor: focusColor);}static const ColorScheme lightColorScheme = ColorScheme(primary: Color(0xFFB93C5D),onPrimary: Colors.black,secondary: Color(0xFFEFF3F3),onSecondary: Color(0xFF322942),error: Colors.redAccent,onError: Colors.white,background: Color(0xFFE6EBEB),onBackground: Colors.white,surface: Color(0xFFFAFBFB),onSurface: Color(0xFF241E30),brightness: Brightness.light,);static const ColorScheme darkColorScheme = ColorScheme(primary: Color(0xFFFF8383),secondary: Color(0xFF4D1F7C),background: Color(0xFF241E30),surface: Color(0xFF1F1929),onBackground: Color(0x0DFFFFFF),error: Colors.redAccent,onError: Colors.white,onPrimary: Colors.white,onSecondary: Colors.white,onSurface: Colors.white,brightness: Brightness.dark,);
}

是的!我们刚刚为我们的应用程序创建了一个漂亮的主题。现在怎么办?

设置 ThemeData

MaterialApp 中设置所需的主题。

class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false,title: 'Flutter Demo',themeMode: ThemeMode.light, //or ThemeMode.darktheme: GlobalThemData.lightThemeData,darkTheme: GlobalThemData.darkThemeData,home: const ShowCaseHome(),);}
}

这将为您的应用程序提供默认的浅色主题,您可以将模式更改为深色。您可以探索 InheritedWidget 或 Provider 的强大功能,以实现动态切换。这不在本文的讨论范围之内,如有需要,我们可以在今后的文章中详细讨论。

希望您能得到一些有价值的信息,感谢您的阅读🤗。


https://medium.com/@nikhithsunil/theme-your-flutter-app-a-guide-to-themedata-and-colorscheme-d8bca920a6b5


http://www.mrgr.cn/p/61218062

相关文章

Linux:进程信号

生活角度的信号 a.信号在生活中,随时可以产生(信号的产生和我是异步的) b.你能认识这个信号 c.我们知道信号产生了,我能识别这个信号,信号该怎么处理 d.我们可能正在做着更重要的事情,把到来的信号暂不处理(1.我记得这个事 2.…

分布式 ID 的实现方案——Java全栈知识(13)

分布式 ID 的实现方案 当我们分表的情况下,如何实现全局唯一 ID 也是一个问题,数据库的唯一索引在 分布式 ID 也就是全局唯一 ID 生产方案需要满足以下几个条件: 高可用高性能安全性自增性唯一性 1、UUID UUID(Universally Un…

cobalt strike安装教程

将本地IP和密码填入:./teamserver 192.168.xx.xx 密码 启动成功

初识C语言——第十五天

初识结构体1 //结构体可以让C语言创建新的类型出来 //创建一个学生struct Stu {char name[20];int age;double score;}; //创建一个书的类型 struct Book {char name[20];float price;char id[30]; };//int main() //{ // struct Stu s { "张三",20,85.5 };//结…

You don’t have permission.

The document “XXX” could not be saved. You don’t have permission. 1.查看修改了iOS系统库导致的, 根据提示, 进入到"XXX"文件中, 然后commandz回退/取消 2. Xcode 调试遇到的报错(持续更新)

WDS+MDT网络启动自动部署windows(十七)MDT中文变量,描述,组织单位OU

简介 这简直就是歧视,在MDT使用变量时,数据库设置时,居然不能用中文。 计算机描述,我将在数据库中设置为使用人,主要是其他地方也不方便看。 描述是存在注册表中的,未来自动化也将会使用使用人这个字段,用来注册OCS这样,有标签,使用人字段的软件。 方向 解决MDT/BDD无…

蓝桥杯练习系统(算法训练)ALGO-950 逆序数奇偶

资源限制 内存限制:256.0MB C/C时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s 问题描述 老虎moreD是一个勤于思考的青年,线性代数行列式时,其定义中提到了逆序数这一概念。不过众所周知我们…

【Linux】17. 进程间通信 --- 管道

1. 什么是进程间通信(进程间通信的目的) 数据传输:一个进程需要将它的数据发送给另一个进程 资源共享:多个进程之间共享同样的资源。 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了…

刷题训练之模拟

> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:熟练掌握模拟算法。 > 毒鸡汤:学习,学习,再学习 ! 学,然后知不足。 > 专栏选自:刷题训…

Ansible——playbook编写

一、简介 1.什么是playbook Ansible Playbook 是设定自动化任务的一种蓝图,可在无需人工干预或有限干预的前提下执行复杂的 IT 操作。Ansible Playbook 对一组或一类共同构成 Ansible 清单的主机执行。 Ansible Playbook 本质上是一些框架,是一些预先编…

pytest教程-41-钩子函数-pytest_runtest_teardown

领取资料,咨询答疑,请➕wei: June__Go 上一小节我们学习了pytest_runtest_call钩子函数的使用方法,本小节我们讲解一下pytest_runtest_teardown钩子函数的使用方法。 pytest_runtest_teardown 钩子函数在每个测试用例执行完成后被调用&…

商务分析方法与工具(五):Python的趣味快捷-文件和文件夹操作自动化

Tips:"分享是快乐的源泉💧,在我的博客里,不仅有知识的海洋🌊,还有满满的正能量加持💪,快来和我一起分享这份快乐吧😊! 喜欢我的博客的话,记得…

Web前端三大主流框架是什么?

Web前端开发领域的三大主流框架分别是Angular、React和Vue.js。它们在Web开发领域中占据着重要的地位,各自拥有独特的特点和优势。 Angular Angular是一个由Google开发的前端框架,最初版本称为AngularJS,后来升级为Angular。它是一个完整的…

五种算法(BWO、RUN、SO、HO、GWO)求解复杂城市地形下无人机路径规划,可以修改障碍物及起始点(MATLAB)

一、算法介绍 (1)白鲸优化算法BWO 参考文献:Zhong C, Li G, Meng Z. Beluga whale optimization: A novel nature-inspired metaheuristic algorithm[J]. Knowledge-Based Systems, 2022, 109215. (2)龙格-库塔优化…

三维建模技术在AI去衣中的奇妙应用

引言: 随着计算机视觉和深度学习技术的迅猛发展,人工智能(AI)在图像处理和理解方面取得了显著进展。其中,一个颇具争议却技术上引人入胜的应用便是AI去衣——即使用AI技术从图片或视频中移除人物的衣物。尽管这技术常因…

WDS+MDT网络启动自动部署windows(十六)计算机自动进入指定OU

简介 新装计算机总是在默认电脑,不方便配置终端计算机策略权限。 要想办法让MDT装好的计算机,自动进入指定组织单位OU。 dsquery 大概意思是 domain server query ,就是域服务器搜索的意思。 在域控执行 dsquery ou 先看看OU是怎么用LDAP表示的。 从左到右,OU,逐级的组…

将要上市的自动驾驶新书《自动驾驶系统开发》中摘录各章片段 1

以下摘录一些章节片段: 1. 概论 自动驾驶系统的认知中有一些模糊的地方,比如自动驾驶系统如何定义的问题,自动驾驶的研发为什么会有那么多的子模块,怎么才算自动驾驶落地等等。本章想先给读者一个概括介绍,了解自动驾…

算法学习(6)-最短路径

目录 Floyd-Warshall算法 Dijkstra算法 Bellman-Ford算法 Bellman-Ford的队列优化 最短路径算法对比分析 Floyd-Warshall算法 现在回到问题:如何求任意两点之间的最短路径呢? 通过之前的学习, 我们知道通过深度或广度优先搜索可以求出两…

算法系列--多源BFS问题

💕"对相爱的人来说,对方的心意,才是最好的房子。"💕 作者:Lvzi 文章主要内容:算法系列–多源BFS问题 大家好,今天为大家带来的是算法系列--多源BFS问题 前言: 之前我们已经学习过单源的最短路问…

php基础知识快速入门

一、PHP基本知识 1、php介绍: php是一种创建动态交互性的强有力的服务器脚本语言,PHP是开源免费的,并且使用广泛。PHP是解释性语言,按顺序从上往下执行,无需编译,直接运行。PHP脚本在服务器上运行。 2、ph…