写点什么

flutter 系列之: 在 flutter 中自定义 themes

作者:程序那些事
  • 2023-03-06
    广东
  • 本文字数:1465 字

    阅读完需:约 5 分钟

简介

一般情况下我们在 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。

总结

当我们需要自定义 theme 或者不同 theme 的时候,就可以考虑使用本文中使用的方法来进行 theme 的自定义了。

本文的例子:https://github.com/ddean2009/learn-flutter.git

用户头像

关注公众号:程序那些事,更多精彩等着你! 2020-06-07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
flutter系列之:在flutter中自定义themes_flutter_程序那些事_InfoQ写作社区