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

news2024/12/26 23:50:22

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

在本文中,我计划仅关注 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.dark
      theme: 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.coloradmin.cn/o/1653141.html

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

相关文章

LeetCode70:爬楼梯

题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 解题思想 1.确定dp数组以及下标的含义 dp[i]: 爬到第i层楼梯,有dp[i]种方法 2.确定递推公式 从dp[i]的定义可以…

旋转测径仪的常见故障和排除方法

关键字: 旋转测径仪,测径仪常见故障,测径仪故障排除方法,测径仪维护,测径仪较零 点击 “开始测量”按钮时提示“初始化失败!”无法进行测量。 ◆ 检查控制柜面板“工作”指示灯(绿)是否点亮; ◆ 最小化软件窗口,查看…

解密某游戏的数据加密

前言 最近有个兄弟通过我的视频号加我,咨询能否将这个dubo游戏游戏开始前就将数据拿到从而进行押注,于是通过抓包工具测试了下,发现数据有时候是明文,有时候确实密文,大致看了下有这几种加密:Md5aes、Md5&a…

用Pycharm对图片中表格进行文字识别,并导出到xlsx文件中

需要使用到百度API对图片文字进行识别 在百度智能云官网中注册一个账号百度智能云-登录https://login.bce.baidu.com/ 之后在管理中心里创建应用 创建完成后会得到: 记下一下AppID&API Key&Secret Key这三个值,调用接口时使用。 示例图片&…

字符编码(十六进制)

题目描述 假设一个简易的变长编码规则XUTF:每个字符有一个唯一编号值 unicodeVal(如汉字“华”的编号十进制值是21326),使用1~6个字节进行编码,编码规则如下: 编码格式: 编号值范围编码后字节长度n二进制格式(x 表示有效位,其它为固定位)[0, 2^7)1字节1xxxxxxx[2^7,…

数智算网,链启未来 | 算力网络子链诚邀各方加入

4月28日,在中国移动算力网络大会期间,由中国移动集团主办,中国移动研究院和云能力中心联合承办的“数智算网,链启未来”共链行动算力网络专场会议成功召开。中国移动研究院副院长段晓东,中国移动集团首席专家、云能力中…

Tomcat、MySQL、Redis最大支持说明

文章目录 一、Tomcat二、MySQL三、Redis1、最大连接数2、TPS、QPS3、key和value最大支持 一、Tomcat 查看SpringBoot内置Tomcat的源码,如下: 主要就是看抽象类AbstractEndpoint,可以看到默认的核心线程数10,最大线程数200 通过…

百元挂耳式耳机哪款好?五款高品质一流机型不容错过

开放式耳机以其独特的不入耳设计,大大提升了佩戴的舒适度。相较于传统的入耳式耳机,它巧妙地避免了对耳朵的压迫,降低了中耳炎等潜在风险。不仅如此,开放式耳机还能让你保持对周边声音的灵敏度,无论是户外跑步还是骑行…

umount.nfs : /out:device is busy

-f, --force force unmount (in case of an unreachable NFS system) -l, --lazy detach the filesystem now, and cleanup all later-l 这么牛?现在分离文件系统,稍后再进行清理

【实战】采用jenkins pipeline实现自动构建并部署至k8s

文章目录 前言部署jenkins编写docker-compose-jenkins.yaml配置maven源启动jenkins解锁jenkins Jenkins默认插件及git、镜像仓库、k8s凭证配置host key verification configuration修改为不验证Gitee ssh阿里云镜像仓库ssh编写pipeline安装以下常用插件将kubectl命令文件拷贝到…

Google Pixel4手机刷机+Root+逆向环境详细教程

Google Pixel4手机刷机Root逆向环境配置详细教程 刷机工具下载 Windows10、Google Pixel4手机当前安卓10系统、adb工具、要刷的谷歌原生的Android11最新刷机包、安装google usb驱动、美版临时twrp-3.6.0_11-0-flame.img和美版永久twrp-installer-3.6.0_11-0-flame.zip、Magis…

前端组件库之ant-design-vue

在这里记录一个这个组件库我之前没有发现最近才发现的一个很好用的功能(应该叫功能吧?) 就是 这个flex弹性布局,之前在开发时,一直使用elementUI,是第一次使用这个组件库,所以没有发现这个功能这么好用 你…

适合宝妈的项目,一单20,看似不起眼的小生意,却能闷声发财!

向大家推荐一个小项目,信息差较大,每单至少有20元的利润。目前参与的人还不多,是个不错的机会。操作方法也非常简单,只需利用京东家政券赚取差价。可能很多人是第一次了解到这个——京东竟然还有家政券。 周周近财:让…

线下订单平台操作步揍

收款管理 1微信收款查询 1. 获取微信数据 获取微信数据。通过时间范围 查找微信数据调用第三方接口如下: Map map HttpPost.doPost("https://qyapi.weixin.qq.com/cgi-bin/externalpay/get_bill_list?access_token"ApiUtils.getWxtoken(),args); 其中…

[YOLOv8] 用YOLOv8实现指针式圆形仪表智能读数(二)

最近研究了一个项目,利用python代码实现指针式圆形仪表的自动读数,并将读数结果进行输出,若需要完整数据集和源代码可以私信。 目录 🍓🍓1.yolov8实现圆盘形仪表智能读数 🙋🙋2.表盘指针语义…

【数据分析面试】38.更新图书馆数据(Python)

题目 作为一名精通Python的图书管理员,你正在搭建一个更高效地更新图书数据的系统。 编写一个名为 update_availability 的函数,用于更新数据表中特定 book_id 的 availability 值,并返回更新后的数据表。 注意: 如果找不到 book_id&#…

【触想智能】工业级平板电脑五大特征与应用领域分析

工业级平板电脑是专供工业环境使用的工业控制计算机,也被称为工控一体机。工业级平板电脑基本性能及兼容性与商用平板电脑几乎相同,但是工业级平板电脑更注重在不同环境下的稳定性能,因此,工业级平板电脑与普通的商用平板电脑存在…

使用arthas 定位三方源码中报错行数

程序编译之后和你源java文件会有差异,导致报错行数不是你真实的java文件的行数 代码一共三百多行idea优化过后的 class代码,但是报错在六百多行不想下周源码 这时候使用 jad org.mindrot.jbcrypt.BCrypt 反编译执行的源代码信息确定行数

华火电焰灶,科技打造“新”厨房

家里最大的空气污染源其实来自厨房里的燃气灶!——斯坦福大学发表的《科学进展》期刊 厨房在家庭中占有举足轻重的地位,它不仅是一个烹饪美食的场所,更是家人情感交流的重要空间。厨房大致经历了两次变革,分别是以柴火灶为主体的厨…

Android广播机制简介

文章目录 Android广播机制简介广播的基本概念广播的类型广播的使用场景Android广播的优缺点优点缺点 使用Android广播的一些最佳实践: Android广播机制简介 Android广播是一种轻量级的消息传递机制,用于应用程序之间或系统与应用程序之间进行通信。它类似于订阅-发…