Flutter 3:如何扩展 ThemeData

  • 发表于
  • flutter

Flutter 3.0 的发布,它带来了一个更好的解决方案:ThemeExtension类。

新的解决方案

我们将制作 bootstrap 风格的配色方案:

Flutter 3:如何扩展 ThemeData

首先,创建一个文件custom_color_scheme.dart

import 'package:flutter/material.dart';
@immutable
class CustomColors extends ThemeExtension<CustomColors> {
const CustomColors({
required this.success,
required this.info,
required this.warning,
required this.danger,
});
final Color? success;
final Color? info;
final Color? warning;
final Color? danger;
@override
CustomColors copyWith({
Color? success,
Color? info,
Color? warning,
Color? danger,
}) {
return CustomColors(
success: success ?? this.success,
info: info ?? this.info,
warning: warning ?? this.warning,
danger: danger ?? this.danger,
);
}
// Controls how the properties change on theme changes
@override
CustomColors lerp(ThemeExtension<CustomColors>? other, double t) {
if (other is! CustomColors) {
return this;
}
return CustomColors(
success: Color.lerp(success, other.success, t),
info: Color.lerp(info, other.info, t),
warning: Color.lerp(warning, other.warning, t),
danger: Color.lerp(danger, other.danger, t),
);
}
// Controls how it displays when the instance is being passed
// to the `print()` method.
@override
String toString() => 'CustomColors('
'success: $success, info: $info, warning: $info, danger: $danger'
')';
// the light theme
static const light = CustomColors(
success: Color(0xff28a745),
info: Color(0xff17a2b8),
warning: Color(0xffffc107),
danger: Color(0xffdc3545),
);
// the dark theme
static const dark = CustomColors(
success: Color(0xff00bc8c),
info: Color(0xff17a2b8),
warning: Color(0xfff39c12),
danger: Color(0xffe74c3c),
);
}

接下来,将主题添加到您的MaterialApp小部件:

MaterialApp(
theme: ThemeData.light().copyWith(
extensions: <ThemeExtension<dynamic>>[
CustomColors.light,
],
),
darkTheme: ThemeData.dark().copyWith(
extensions: <ThemeExtension<dynamic>>[
CustomColors.dark,
],
),
// other parameters...
);

然后在您的组件中,导入custom_color_scheme.dart文件。您将能够立即使用这些颜色。

在构建方法中:

// Get the `CustomColors` typed object in the `ThemeData` extension
final customColors = Theme.of(context).extension<CustomColors>()!;
TextButton(
style: TextButton.styleFrom(
backgroundColor: customColors.success,
primary: Colors.white,
),
child: const Text('Success'),
onPressed: () {},
)

黑暗模式

在您的设备上切换主题亮度,您可以看到颜色已更新。

除了颜色之外,我们还可以在主题中添加其他属性,例如组件之间的间距、按钮填充、文本大小等。虽然将所有内容都放在同一个对象中并不是一个好主意;为了使您的代码库更加结构化,您可以创建更多的类,例如CustomTextStyleLayoutTheme并将它们放在extensionsThemeData 的参数中。