Flutter主题创建与管理插件create_theme的使用
Flutter主题创建与管理插件create_theme的使用
create_theme 是一个用于生成 Flutter ThemeExtension 的工具,可以帮助开发者更方便地管理和扩展主题。通过该插件,你可以轻松定义主题属性并自动生成相关代码。
安装
在项目中添加以下依赖:
flutter pub add create_theme_annotation
flutter pub add --dev create_theme
示例代码
my_widget.dart
import 'package:create_theme_annotation/create_theme_annotation.dart';
import 'package:flutter/material.dart';
part 'my_widget.g.dart'; // 自动生成的文件
// 默认主题数据生成函数
MyWidgetThemeData _createDefault(ThemeData theme) {
return MyWidgetThemeData(
headerColor: theme.colorScheme.primary, // 使用系统主题的颜色方案
headerTextStyle: TextStyle(
color: theme.colorScheme.onPrimary, // 设置文本颜色
),
backgroundColor: theme.scaffoldBackgroundColor, // 背景颜色
);
}
// 使用 @CreateTheme 注解定义主题
@CreateTheme(
themeProperties: {
'headerColor': CreateThemeColor(), // 定义颜色属性
'headerTextStyle': CreateThemeTextStyle(), // 定义文本样式属性
'backgroundColor': CreateThemeColor(), // 定义背景颜色属性
},
createDefault: _createDefault, // 提供默认主题生成逻辑
)
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
final theme = MyWidgetTheme.of(context); // 获取主题数据
return Column(
children: [
Material(
color: theme.headerColor, // 使用主题的 headerColor
child: DefaultTextStyle.merge(
style: theme.headerTextStyle, // 使用主题的 headerTextStyle
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: Text('Header'), // 显示标题
),
),
),
),
Expanded(
child: Material(
color: theme.backgroundColor, // 使用主题的 backgroundColor
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: Text('Body'), // 显示正文
),
),
),
),
],
);
}
}
// 自定义颜色属性类
class CreateThemeColor extends CreateThemeProperties<Color> {
const CreateThemeColor() : super(propertiesType: Color, lerp: Color.lerp);
}
// 自定义文本样式属性类
class CreateThemeTextStyle extends CreateThemeProperties<TextStyle> {
const CreateThemeTextStyle()
: super(propertiesType: TextStyle, lerp: TextStyle.lerp);
}
自动生成的 my_widget.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'my_widget.dart';
// 主题数据类
class MyWidgetThemeData extends ThemeExtension<MyWidgetThemeData> {
const MyWidgetThemeData({
this.headerColor,
this.headerTextStyle,
this.backgroundColor,
});
final Color? headerColor;
final TextStyle? headerTextStyle;
final Color? backgroundColor;
// 复制主题数据
[@override](/user/override)
MyWidgetThemeData copyWith({
Color? headerColor,
TextStyle? headerTextStyle,
Color? backgroundColor,
}) {
return MyWidgetThemeData(
headerColor: headerColor ?? this.headerColor,
headerTextStyle: headerTextStyle ?? this.headerTextStyle,
backgroundColor: backgroundColor ?? this.backgroundColor,
);
}
// 插值主题数据
[@override](/user/override)
MyWidgetThemeData lerp(
ThemeExtension<MyWidgetThemeData>? other,
double t,
) {
if (other is! MyWidgetThemeData) return this;
return MyWidgetThemeData(
headerColor: Color.lerp(headerColor, other.headerColor, t),
headerTextStyle:
TextStyle.lerp(headerTextStyle, other.headerTextStyle, t),
backgroundColor: Color.lerp(backgroundColor, other.backgroundColor, t),
);
}
// 合并主题数据
MyWidgetThemeData merge(MyWidgetThemeData? other) {
if (other == null) return this;
return copyWith(
headerColor: other.headerColor,
headerTextStyle: other.headerTextStyle,
backgroundColor: other.backgroundColor,
);
}
[@override](/user/override)
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is MyWidgetThemeData &&
other.headerColor == headerColor &&
other.headerTextStyle == headerTextStyle &&
other.backgroundColor == backgroundColor;
}
[@override](/user/override)
int get hashCode {
return Object.hashAll([
headerColor,
headerTextStyle,
backgroundColor,
]);
}
}
// 主题上下文提供器
class MyWidgetTheme extends InheritedWidget {
const MyWidgetTheme({
super.key,
required this.theme,
required super.child,
});
final MyWidgetThemeData theme;
[@override](/user/override)
bool updateShouldNotify(MyWidgetTheme oldWidget) {
return oldWidget.theme != theme;
}
// 获取主题数据
static MyWidgetThemeData of(BuildContext context) {
final widget = context.dependOnInheritedWidgetOfExactType<MyWidgetTheme>();
final localTheme = widget?.theme;
final theme = Theme.of(context);
final rootTheme = theme.extensions[MyWidgetThemeData] as MyWidgetThemeData?;
final MyWidgetThemeData defaultTheme = _createDefault(theme);
final result = defaultTheme.merge(rootTheme?.merge(localTheme));
return result;
}
}
运行示例
以下是完整的运行示例代码:
import 'package:example/src/my_widget.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
runApp(const App());
}
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return const MaterialApp(
themeMode: ThemeMode.system, // 系统主题模式
home: Home(),
);
}
}
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Create Theme demo'), // 应用标题
),
body: const SafeArea(
child: MyWidget(), // 使用自定义组件
),
);
}
}
更多关于Flutter主题创建与管理插件create_theme的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter主题创建与管理插件create_theme的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
create_theme 是一个用于 Flutter 的主题创建与管理的插件,它可以帮助开发者更轻松地定义和管理应用的主题。通过 create_theme,你可以创建自定义的主题,并在应用的不同部分中使用这些主题。
安装
首先,你需要在 pubspec.yaml 文件中添加 create_theme 依赖:
dependencies:
flutter:
sdk: flutter
create_theme: ^1.0.0 # 请确保使用最新版本
然后运行 flutter pub get 来安装依赖。
基本用法
-
创建主题
使用
create_theme插件,你可以定义一个自定义主题。例如:import 'package:create_theme/create_theme.dart'; final myTheme = CreateTheme( primaryColor: Colors.blue, accentColor: Colors.orange, textTheme: TextTheme( headline1: TextStyle(fontSize: 32, fontWeight: FontWeight.bold), bodyText1: TextStyle(fontSize: 16, color: Colors.black), ), ); -
应用主题
在你的
MaterialApp中应用这个主题:import 'package:flutter/material.dart'; import 'package:create_theme/create_theme.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: myTheme.toMaterialTheme(), // 将自定义主题转换为 MaterialTheme home: MyHomePage(), ); } } -
使用主题
在你的 Widget 中使用定义的主题:
class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { final theme = CreateTheme.of(context); // 获取当前主题 return Scaffold( appBar: AppBar( title: Text('My App'), backgroundColor: theme.primaryColor, ), body: Center( child: Text( 'Hello, World!', style: theme.textTheme.headline1, ), ), ); } }
高级用法
-
动态切换主题
你可以使用
CreateTheme来动态切换主题。例如,通过ChangeNotifier或Provider来管理主题状态:import 'package:flutter/material.dart'; import 'package:create_theme/create_theme.dart'; import 'package:provider/provider.dart'; void main() { runApp( ChangeNotifierProvider( create: (_) => ThemeNotifier(), child: MyApp(), ), ); } class ThemeNotifier with ChangeNotifier { CreateTheme _currentTheme = myTheme; CreateTheme get currentTheme => _currentTheme; void toggleTheme() { _currentTheme = _currentTheme == myTheme ? myOtherTheme : myTheme; notifyListeners(); } } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { final themeNotifier = Provider.of<ThemeNotifier>(context); return MaterialApp( title: 'Flutter Demo', theme: themeNotifier.currentTheme.toMaterialTheme(), home: MyHomePage(), ); } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { final themeNotifier = Provider.of<ThemeNotifier>(context); return Scaffold( appBar: AppBar( title: Text('My App'), ), body: Center( child: ElevatedButton( onPressed: () => themeNotifier.toggleTheme(), child: Text('Toggle Theme'), ), ), ); } } -
扩展主题
你可以扩展
CreateTheme来添加更多的自定义属性:class MyCustomTheme extends CreateTheme { final Color customColor; MyCustomTheme({ required this.customColor, required Color primaryColor, required Color accentColor, required TextTheme textTheme, }) : super( primaryColor: primaryColor, accentColor: accentColor, textTheme: textTheme, ); } final myCustomTheme = MyCustomTheme( customColor: Colors.purple, primaryColor: Colors.blue, accentColor: Colors.orange, textTheme: TextTheme( headline1: TextStyle(fontSize: 32, fontWeight: FontWeight.bold), bodyText1: TextStyle(fontSize: 16, color: Colors.black), ), );

