Flutter 中优雅切换应用主题的组件
视频
https://www.bilibili.com/video/BV1wD421n75p/
前言
Adaptive Theme 这个组件通过包裹 MaterialApp 的方式整体管理 theme 主题,实现如下功能:
- 切换 light、dark、system 三种模式
- 自定义色彩
- 保存主题选择
- 开启调试按钮
参考
https://pub.dev/packages/adaptive_theme
https://flutter.ducafecat.com/pubs/adaptive_theme-package-info
https://github.com/birjuvachhani/adaptive_theme
步骤
安装配置
https://pub.dev/packages/adaptive_theme
pubspec.yaml
dependencies:
flutter:
sdk: flutter
adaptive_theme: ^3.6.0
lib/main.dart
class MyApp extends StatelessWidget {
const MyApp({
super.key});
Widget build(BuildContext context) {
return AdaptiveTheme(
light: ThemeData.light(useMaterial3: true),
dark: ThemeData.dark(useMaterial3: true),
initial: AdaptiveThemeMode.light,
debugShowFloatingThemeButton: true,
builder: (theme, darkTheme) => MaterialApp(
title: 'Flutter Demo',
theme: theme,
darkTheme: darkTheme,
home: const MyHomePage(title: 'Flutter Demo Home Page'),
),
);
}
}
debugShowFloatingThemeButton 开启调试按钮
设置主题
设置亮色
ElevatedButton(
onPressed: () {
AdaptiveTheme.of(context).setLight();
},
child: const Text('Set Light Theme'),
),
设置暗色
ElevatedButton(
onPressed: () {
AdaptiveTheme.of(context).setDark();
},
child: const Text('Set Dark Theme'),
),
设置系统
ElevatedButton(
onPressed: () {
AdaptiveTheme.of(context).setSystem();
},
child: const Text('Set System Theme'),
),
toggle 切换
ElevatedButton(
onPressed: () {
AdaptiveTheme.of(context).toggleThemeMode();
},
child: const Text('Toggle Theme Mode'),
),
重置样式
ElevatedButton(
onPressed: () {
AdaptiveTheme.of(context).reset();
},
child: const Text('Reset Theme'),
),
监听样式切换
// 监听当前样式
ValueListenableBuilder(
valueListenable: AdaptiveTheme.of(context).modeChangeNotifier,
builder: (_, mode, child) {
return Text(mode.modeName);
},
),
自定义样式颜色
ElevatedButton(
onPressed: () {
AdaptiveTheme.of(context).setTheme(
light: ThemeData(
useMaterial3: true,
brightness: Brightness.light,
colorSchemeSeed: Colors.green,
),
dark: ThemeData(
useMaterial3: true,
brightness: Brightness.dark,
colorSchemeSeed: Colors.brown,
),
);
},
child: const Text('Change Theme Color'),
),
读取配置
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final savedThemeMode = await AdaptiveTheme.getThemeMode();
runApp(MyApp(savedThemeMode: savedThemeMode));
}
class MyApp extends StatelessWidget {
final AdaptiveThemeMode? savedThemeMode;
const MyApp({
super.key, this.savedThemeMode});
// This widget is the root of your application.
Widget build(BuildContext context) {
return AdaptiveTheme(
light: ThemeData.light(useMaterial3: true),
dark: ThemeData.dark(useMaterial3: true),
initial: savedThemeMode ?? AdaptiveThemeMode.light,
debugShowFloatingThemeButton: true,
builder: (theme, darkTheme) => MaterialApp(
title: 'Flutter Demo',
theme: theme,
darkTheme: darkTheme,
home: const MyHomePage(title: 'Flutter Demo Home Page'),
),
);
}
}
不要覆盖 key
本地离线采用 shared_preferences 组件,所以不要覆盖键值 adaptive_theme_preferences
https://github.com/BirjuVachhani/adaptive_theme/blob/main/lib/src/adaptive_theme.dart
/// Key used to store theme information into shared-preferences. If you want
/// to persist theme mode changes even after shared-preferences
/// is cleared (e.g. after log out), do not remove this [prefKey] key from
/// shared-preferences.
static const String prefKey = 'adaptive_theme_preferences';
代码
https://github.com/ducafecat/flutter_develop_tips/tree/main/flutter_application_adaptive_theme
小结
通过使用 Flutter 的 adaptive_theme 组件,我们可以轻松地实现应用主题的切换功能。该组件提供了简单的方法来手动设置浅色或深色主题,并且还可以根据系统定义的主题进行自适应切换。无论是在用户界面上还是在代码层面上,我们可以灵活地控制应用程序的主题外观,为用户提供更好的体验。
感谢阅读本文
如果有什么建议,请在评论中让我知道。我很乐意改进。
flutter 学习路径
- Flutter 优秀插件推荐 https://flutter.ducafecat.com
- Flutter 基础篇1 - Dart 语言学习 https://ducafecat.com/course/dart-learn
- Flutter 基础篇2 - 快速上手 https://ducafecat.com/course/flutter-quickstart-learn
- Flutter 实战1 - Getx Woo 电商APP https://ducafecat.com/course/flutter-woo
- Flutter 实战2 - 上架指南 Apple Store、Google Play https://ducafecat.com/course/flutter-upload-apple-google
- Flutter 基础篇3 - 仿微信朋友圈 https://ducafecat.com/course/flutter-wechat
- Flutter 实战3 - 腾讯 tim 即时通讯开发 https://ducafecat.com/course/flutter-tim
© 猫哥
ducafecat.com
end