Flutter动态主题颜色插件dynamic_color_theme的使用
Flutter动态主题颜色插件dynamic_color_theme的使用
动态主题颜色插件简介
dynamic_color_theme
插件允许您动态更改应用的主题颜色,并根据新的颜色自动切换浅色和深色模式。此外,通过将颜色和深色模式保存到共享偏好设置中,可以跨重启持久化颜色值。
安装
在pubspec.yaml
文件中添加依赖:
dependencies:
dynamic_color_theme: ^2.0.0
导入插件:
import 'package:dynamic_color_theme/dynamic_color_theme.dart';
如果您想使用内置的颜色选择器对话框,还需导入以下内容:
import 'package:dynamic_color_theme/color_picker_dialog.dart';
使用方法
包裹主小部件
为了使用dynamic_color_theme
,您需要将主小部件包裹在DynamicColorTheme
中:
const kFuchsia = const Color(0xFF880E4F);
const kWhite = Colors.white;
const kLightGrey = const Color(0xFFE8E8E8);
const kDarkGrey = const Color(0xFF303030);
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return DynamicColorTheme(
data: (Color color, bool isDark) {
return _buildTheme(color, isDark); // 自定义构建主题的方法
},
defaultColor: kFuchsia,
defaultIsDark: false,
themedWidgetBuilder: (BuildContext context, ThemeData theme) {
return MaterialApp(
home: MyHomePage(title: 'Dynamic Color Theme'),
theme: theme,
title: 'Flutter Demo',
);
},
);
}
// 示例构建主题的方法
ThemeData _buildTheme(Color accentColor, bool isDark) {
final ThemeData base = isDark ? ThemeData.dark() : ThemeData.light();
final Color primaryColor = isDark ? kDarkGrey : kWhite;
return base.copyWith(
accentColor: accentColor,
accentTextTheme: _buildTextTheme(base.accentTextTheme, accentColor),
cardColor: primaryColor,
floatingActionButtonTheme: base.floatingActionButtonTheme.copyWith(
backgroundColor: accentColor,
),
iconTheme: base.iconTheme.copyWith(
color: accentColor,
),
primaryColor: primaryColor,
primaryIconTheme: base.primaryIconTheme.copyWith(
color: accentColor,
),
primaryTextTheme: _buildTextTheme(base.primaryTextTheme, accentColor),
scaffoldBackgroundColor: primaryColor,
textSelectionTheme: _buildTextSelectionTheme(base.textSelectionTheme, accentColor, isDark),
textTheme: _buildTextTheme(base.textTheme, accentColor),
);
}
TextTheme _buildTextTheme(TextTheme base, Color color) {
return base.copyWith(
bodyText2: base.bodyText2!.copyWith(
fontSize: 16,
),
bodyText1: base.bodyText1!.copyWith(
color: color,
fontSize: 16,
fontWeight: FontWeight.bold,
),
button: base.button!.copyWith(
color: color,
),
caption: base.caption!.copyWith(
color: color,
fontSize: 14,
),
headline5: base.headline5!.copyWith(
color: color,
fontSize: 24,
),
subtitle1: base.subtitle1!.copyWith(
color: color,
fontSize: 18,
),
headline6: base.headline6!.copyWith(
color: color,
fontSize: 20,
fontWeight: FontWeight.bold,
),
);
}
TextSelectionThemeData _buildTextSelectionTheme(TextSelectionThemeData base, Color accentColor, bool isDark) {
return base.copyWith(
cursorColor: accentColor,
selectionColor: isDark ? kDarkGrey : kLightGrey,
selectionHandleColor: accentColor,
);
}
}
更改主题
您可以使用提供的函数来更改主题:
void changeColor(Color newColor) {
DynamicColorTheme.of(context).setColor(
color: newColor,
shouldSave: true, // 保存到共享偏好设置
);
}
void changeIsDark(bool isDark) {
DynamicColorTheme.of(context).setIsDark(
isDark: isDark,
shouldSave: true, // 保存到共享偏好设置
);
}
void resetTheme() {
DynamicColorTheme.of(context).resetToSharedPrefsValues();
}
颜色选择器对话框
插件还提供了一个颜色选择器对话框,可以方便地选择颜色并切换深色模式。以下是使用示例:
可取消的对话框
showDialog(
barrierDismissible: false,
builder: (BuildContext context) {
return ColorPickerDialog(
defaultColor: kFuchsia,
defaultIsDark: false,
);
},
context: context,
);
不可取消的对话框
showDialog(
builder: (BuildContext context) {
return WillPopScope(
child: ColorPickerDialog(
defaultColor: kFuchsia,
defaultIsDark: false,
),
onWillPop: () async {
// 如果用户点击对话框外部,重置为共享偏好设置中的值
DynamicColorTheme.of(context).resetToSharedPrefsValues();
return true;
},
);
},
context: context,
);
完整示例Demo
以下是一个完整的示例代码,展示了如何使用dynamic_color_theme
插件创建一个带有动态主题颜色的应用程序:
import 'package:dynamic_color_theme/color_picker_dialog.dart';
import 'package:dynamic_color_theme/dynamic_color_theme.dart';
import 'package:flutter/material.dart';
const kFuchsia = const Color(0xFF880E4F);
const kWhite = Colors.white;
const kLightGrey = const Color(0xFFE8E8E8);
const kDarkGrey = const Color(0xFF303030);
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return DynamicColorTheme(
data: (Color color, bool isDark) {
return _buildTheme(color, isDark);
},
defaultColor: kFuchsia,
defaultIsDark: false,
themedWidgetBuilder: (BuildContext context, ThemeData theme) {
return MaterialApp(
home: MyHomePage(title: 'Dynamic Color Theme'),
theme: theme,
title: 'Flutter Demo',
);
},
);
}
ThemeData _buildTheme(Color accentColor, bool isDark) {
final ThemeData base = isDark ? ThemeData.dark() : ThemeData.light();
final Color primaryColor = isDark ? kDarkGrey : kWhite;
return base.copyWith(
accentColor: accentColor,
accentTextTheme: _buildTextTheme(base.accentTextTheme, accentColor),
cardColor: primaryColor,
floatingActionButtonTheme: base.floatingActionButtonTheme.copyWith(
backgroundColor: accentColor,
),
iconTheme: base.iconTheme.copyWith(
color: accentColor,
),
primaryColor: primaryColor,
primaryIconTheme: base.primaryIconTheme.copyWith(
color: accentColor,
),
primaryTextTheme: _buildTextTheme(base.primaryTextTheme, accentColor),
scaffoldBackgroundColor: primaryColor,
textSelectionTheme: _buildTextSelectionTheme(base.textSelectionTheme, accentColor, isDark),
textTheme: _buildTextTheme(base.textTheme, accentColor),
);
}
TextTheme _buildTextTheme(TextTheme base, Color color) {
return base.copyWith(
bodyText2: base.bodyText2!.copyWith(
fontSize: 16,
),
bodyText1: base.bodyText1!.copyWith(
color: color,
fontSize: 16,
fontWeight: FontWeight.bold,
),
button: base.button!.copyWith(
color: color,
),
caption: base.caption!.copyWith(
color: color,
fontSize: 14,
),
headline5: base.headline5!.copyWith(
color: color,
fontSize: 24,
),
subtitle1: base.subtitle1!.copyWith(
color: color,
fontSize: 18,
),
headline6: base.headline6!.copyWith(
color: color,
fontSize: 20,
fontWeight: FontWeight.bold,
),
);
}
TextSelectionThemeData _buildTextSelectionTheme(TextSelectionThemeData base, Color accentColor, bool isDark) {
return base.copyWith(
cursorColor: accentColor,
selectionColor: isDark ? kDarkGrey : kLightGrey,
selectionHandleColor: accentColor,
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
[@override](/user/override)
Widget build(BuildContext context) {
Color color = DynamicColorTheme.of(context).color;
bool isDark = DynamicColorTheme.of(context).isDark;
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: Text('当前颜色是 $color,是否为深色模式: $isDark'),
),
TextButton(
child: Text(
'切换深色模式',
style: Theme.of(context).textTheme.button,
),
onPressed: () {
DynamicColorTheme.of(context).setIsDark(
isDark: !isDark,
shouldSave: true,
);
},
),
TextButton(
child: Text(
'设置颜色为洋红色!',
style: Theme.of(context).textTheme.button,
),
onPressed: () {
DynamicColorTheme.of(context).setColor(
color: kFuchsia,
shouldSave: true,
);
},
),
],
),
floatingActionButton: FloatingActionButton.extended(
backgroundColor: color,
icon: Icon(Icons.color_lens),
label: Text('选择颜色'),
onPressed: () {
showDialog(
builder: (BuildContext context) {
return WillPopScope(
child: ColorPickerDialog(
defaultColor: kFuchsia,
defaultIsDark: false,
title: '选择你的命运',
cancelButtonText: '算了',
confirmButtonText: '好的',
shouldAutoDetermineDarkMode: true,
shouldShowLabel: true,
),
onWillPop: () async {
DynamicColorTheme.of(context).resetToSharedPrefsValues();
return true;
},
);
},
context: context,
);
},
),
);
}
}
更多关于Flutter动态主题颜色插件dynamic_color_theme的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter动态主题颜色插件dynamic_color_theme的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter中的dynamic_color_theme
插件来实现动态主题颜色切换的代码示例。这个插件允许你根据用户的系统主题(如暗模式和亮模式)自动调整你的应用主题。
首先,确保你已经在pubspec.yaml
文件中添加了dynamic_color_theme
依赖:
dependencies:
flutter:
sdk: flutter
dynamic_color_theme: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,你可以按照以下步骤设置你的应用以支持动态主题颜色。
1. 定义主题数据
在你的main.dart
文件中,首先定义你的主题数据,包括亮模式和暗模式的颜色方案。
import 'package:flutter/material.dart';
import 'package:dynamic_color_theme/dynamic_color_theme.dart';
final LightColorScheme lightScheme = LightColorScheme(
primary: Colors.blue,
onPrimary: Colors.white,
surface: Colors.white,
onSurface: Colors.black,
// 定义其他颜色...
);
final DarkColorScheme darkScheme = DarkColorScheme(
primary: Colors.blueGrey,
onPrimary: Colors.white,
surface: Colors.black,
onSurface: Colors.white,
// 定义其他颜色...
);
2. 创建DynamicTheme
使用DynamicTheme
包装你的MaterialApp,并设置动态颜色方案。
import 'package:flutter/material.dart';
import 'package:dynamic_color_theme/dynamic_color_theme.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DynamicTheme(
defaultBrightness: Brightness.light, // 初始亮度
data: (Brightness brightness) {
return ThemeData(
brightness: brightness,
colorScheme: brightness == Brightness.light
? ColorScheme.fromSwatch(
primarySwatch: lightScheme.primary,
).copyWith(
backgroundColor: lightScheme.surface,
primaryColor: lightScheme.primary,
onPrimary: lightScheme.onPrimary,
onSurface: lightScheme.onSurface,
// 应用其他颜色...
)
: ColorScheme.fromSwatch(
primarySwatch: darkScheme.primary,
).copyWith(
backgroundColor: darkScheme.surface,
primaryColor: darkScheme.primary,
onPrimary: darkScheme.onPrimary,
onSurface: darkScheme.onSurface,
// 应用其他颜色...
),
);
},
themedWidgetBuilder: (BuildContext context, ThemeData theme, Widget? child) {
return MaterialApp(
title: 'Flutter Demo',
theme: theme,
home: MyHomePage(),
);
},
);
}
}
3. 创建主页面
创建一个简单的页面来展示主题效果。
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Dynamic Theme Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You are in ${Theme.of(context).brightness == Brightness.light ? 'Light' : 'Dark'} mode',
style: TextStyle(color: theme.colorScheme.onSurface),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// 切换主题(这里只是一个示例,实际应用中可能需要持久化用户的选择)
DynamicTheme.of(context).setBrightness(
Theme.of(context).brightness == Brightness.light
? Brightness.dark
: Brightness.light,
);
},
child: Text(
'Switch Theme',
style: TextStyle(color: theme.colorScheme.onPrimary),
),
),
],
),
),
);
}
}
4. 运行应用
现在,你可以运行你的Flutter应用,并看到根据系统主题自动调整的主题颜色。此外,点击按钮可以手动切换亮模式和暗模式。
这个示例展示了如何使用dynamic_color_theme
插件来为你的Flutter应用实现动态主题颜色切换。你可以根据自己的需求进一步自定义和扩展这个示例。