Flutter学习之实现自定义themes详解
作者:程序那些事 发布时间:2022-04-17 17:20:49
简介
一般情况下我们在flutter中搭建的app基本上都是用的是MaterialApp这种设计模式,MaterialApp中为我们接下来使用的按钮,菜单等提供了统一的样式,那么这种样式能不能进行修改或者自定义呢?
答案是肯定的,一起来看看吧。
MaterialApp中的themes
MaterialApp也是一种StatefulWidget,在MaterialApp中跟theme相关的属性有这样几个:
final ThemeData? theme;
final ThemeData? darkTheme;
final ThemeData? highContrastTheme;
final ThemeData? highContrastDarkTheme;
final ThemeMode? themeMode;
先来看下ThemeMode的定义:
enum ThemeMode {
system,
light,
dark,
}
ThemeMode是一个枚举类,里面有三个枚举值,分别是system,light和dark。
我们都知道现在手机有一个暗黑模式,ThemeMode的这三种模式就是为了适应暗黑模式而生的。
system表示是系统默认的模式,light是明亮模式,dark是暗黑模式。
而ThemeData则定义了主题中各种组件或者行动的配色。
那么如果我们想要实现自定义themes的功能,就可以利用这个ThemeData类来重写其中要重写的颜色。
ThemeData中还有专门为color变化定义的ColorScheme,还有为Text变化设置的TextTheme,这两个theme实际上是一系列的color集合。
除了ThemeData,flutter中还有一个类叫做Theme。
Theme是一个StatelessWidget,这个widget中包含了ThemeData,它提供了一个Theme.of方法来让子widget获得最近的ThemeData数据。
这就意味着,在flutter中,子widget可以使用和父widget不同的主题,非常的棒。
自定义themes的使用
那么如何使用自定义themes呢?有两种方式。
第一种就是在使用MaterialApp的时候传入自定义的themes,如下所示:
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
但是这种操作实际是传入了一个全新的ThemeData,假如我们只想修改部分ThemeData中的数据应该如何处理呢?
我们可以使用Theme.of方法从当前的Theme中拷贝一份,然后再调用copyWith方法,传入要修改的自定义属性即可。
如下所示:
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: Theme.of(context).copyWith(useMaterial3: true),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
前面我们提到了Theme这个widget,我们还可以将要自定义Theme的widget用Theme包裹起来,理论上我们可以将任何widget都用Theme来进行包装。
比如之前的floatingActionButton的实现是直接返回一个FloatingActionButton:
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
)
然后我们可以把FloatingActionButton用Theme包装起来,如下所示:
floatingActionButton: Theme(
data: Theme.of(context).copyWith(focusColor: Colors.yellow),
child: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
)
这样不同的组件就拥有了不同的theme。
来源:https://juejin.cn/post/7207242529095598139


猜你喜欢
- 本文实例讲述了Java简单实现约瑟夫环算法。分享给大家供大家参考,具体如下:1.算法背景:罗马人攻占了乔塔帕特,41人藏在一个山洞中躲过了这
- 会话技术会话:一次会话中包含多次请求和响应。一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止功能:在一次会话的范围内
- 方法一public static boolean isTablet(Context context) {
- 如下所示:private void readImage(String filename) throws FileNotFound
- 构造函数public class FileDemo { public static void
- 只要了解过多线程,我们就知道线程开始的顺序跟执行的顺序是不一样的。如果只是创建三个线程然后执行,最后的执行顺序是不可预期的。这是因为在创建完
- 首先是,在不同的AS中,gradle版本不同,下载的sdk版本不同,这些,都在gradle(Project、Models)相关代码里调过来就
- @ApiModel使用场景在实体类上边使用,标记类时swagger的解析类概述提供有关swagger模型的其它信息,类将在操作中用作类型时自
- 之前我一直认为 Mybatis 框架下已经实现预编译机制,很多东西都封装好了,应该基本上不会再有 SQL 注入问题了。近期在渗透中发现,在实
- 本文实例讲述了C#远程发送和接收数据流生成图片的方法。分享给大家供大家参考。具体如下:将图片转成数据流方式发送到远程服务,在通过服务器后台程
- 我就废话不多说了,大家还是直接看代码吧~ public static void main(String[] args) { &n
- 不同的事件源可以产生不同类别的事件。例如,按钮可以发送一个ActionEvent对象,而窗口可以发送WindowEvent对象。AWT时间处
- 1. 编写目的最简单的例子,Springboot整合Redis。2. 详细过程pom 文件添加依赖 <!-- https:
- 当需要重绘TabControl的背景颜色时,有两种方法。方法一网上有很多文章介绍,将tabControl的DrawMode属性设为Owner
- 本文实例讲述了C#同步网络时间的方法。分享给大家供大家参考。具体分析如下:客户的机器的系统时间经常出错,导致给他们做的软件无法正常使用,所以
- 前言Vector是java.util包中的一个类。 SynchronizedList是java.util.Collections中的一个静态
- 二维码是什么二维码 QR Code,全称为:Quick Response Code,最早用于日本汽车制造业追踪零部件。QR现有40个标准版本
- 为什么要用Flyway在日常开发中,我们经常会遇到下面的问题:自己写的SQL忘了在所有环境执行;别人写的SQL我们不能确定是否都在所有环境执
- 本文实例讲述了Java基于栈方式解决汉诺塔问题。分享给大家供大家参考,具体如下:/** * 栈方式非递归汉诺塔 * @author zy *
- 一、项目介绍【知识准备】①Android Interface definition language(aidl,android接口定义语言)