flutter系列之:在flutter中自定义themes
简介
一般来说,我们在flutter中构建的应用程序基本上都使用了Material应用程序的设计模式。Material应用程序为我们接下来使用的按钮和菜单提供了统一的风格。这种风格可以修改或定制吗?
答案是肯定的,让我们看看。
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变化设置的textttheme。这两个theme实际上是一系列的color集合。
除Themedata外,flutter中还有一个类别叫Theme。
Theme是一个包含Themedata的Statelesswidget,它提供了一个Themedata.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的自定义了。