Flutter主题管理插件x_theme_provider的使用
Flutter主题管理插件x_theme_provider的使用
为什么使用ThemeProvider?
- 与
MaterialApp
和CupertinoApp
无缝集成。 - 轻松实现多主题管理。
- 简化主题切换操作。
- 提供对暗色模式、亮色模式、系统模式、下一个主题、上一个主题和切换主题的全面控制。
- 可以持久化所选的主题。
演示: Theme Provider。
使用方法
将你的XApp
包裹在ThemeProvider
中:
class YourApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return ThemeProvider(
theme: YourMaterialAppTheme(), // 或者 DefaultMaterialAppTheme
builder: (theme) => MaterialApp(
title: '您的应用标题',
theme: theme,
home: YourHomePage(),
),
);
}
}
ThemeProvider
处理了MaterialApp
中的darkTheme
和themeMode
。
切换主题
ThemeProvider.of(context).dark(); // 切换到暗色主题
ThemeProvider.of(context).light(); // 切换到亮色主题
ThemeProvider.of(context).system(); // 切换到系统主题
ThemeProvider.of(context).toggle(); // 切换当前主题
ThemeProvider.of(context).next(); // 切换到下一个主题
ThemeProvider.of(context).previous(); // 切换到上一个主题
ThemeProvider.of(context).index = themeIndex; // 设置主题索引
创建自定义主题
class YourMaterialAppTheme extends AppTheme<ThemeData> {
YourMaterialAppTheme() : super(light, dark);
final static ThemeData light = ThemeData(
useMaterial3: true,
brightness: Brightness.light,
colorSchemeSeed: Colors.purple,
);
final static ThemeData dark = ThemeData(
useMaterial3: true,
brightness: Brightness.dark,
colorSchemeSeed: Colors.purple,
);
}
使用CupertinoApp
只需使用DefaultCupertinoTheme
或自定义主题:
class YourApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return ThemeProvider(
theme: YourCupertinoAppTheme(),
builder: (theme) => CupertinoApp(
title: '您的应用标题',
theme: theme,
home: YourHomePage(),
),
);
}
}
监听主题变化
ThemeProvider.of(context).changeNotifier.addListener(() {
// 执行您的操作,或者
// 持久化状态如 pref.setX(key, ThemeProvider.of(context).jsonString)
});
或者通过UI监听变化:
ValueListenableBuilder(
valueListenable: ThemeProvider.of(context).changeNotifier,
...
);
更多功能
// 获取当前主题?
Theme.of(context);
// 获取当前主题模式?
ThemeProvider.of(context).mode;
// 获取或设置当前主题索引?
ThemeProvider.of(context).index;
// 持久化能力?
ThemeProvider.of(context).jsonString;
ThemeProvider(
init: jsonString,
builder: ...
);
// 多主题?
ThemeProvider(
themes: YourThemesList,
builder: ...
);
// 并调用 next 或 previous 来切换主题。
喜欢Cross Theme Provider?
表达您的喜爱,通过给仓库点星,或者您可以:
未来计划
- 下载并安装主题!
示例代码
import 'package:flutter/material.dart';
import 'package:example/src/cupertino_app.dart';
import 'package:x_theme_provider/theme_provider.dart';
import 'package:example/src/my_material_themes.dart';
void main() => runApp(const MyMaterialApp());
class MyMaterialApp extends StatelessWidget {
const MyMaterialApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return ThemeProvider(
themes: themes,
builder: (theme) => MaterialApp(
title: 'Flutter Demo',
theme: theme,
home: const MyHomePage(title: 'Flutter Material Demo'),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text('${widget.title} - ${ThemeProvider.of(context).mode}'),
),
body: buildBody(context, _buildButton, _buildAppSwitch, themes),
floatingActionButton: FloatingActionButton(
onPressed: ThemeProvider.of(context).toggle,
tooltip: '切换主题',
child: const Icon(Icons.contrast),
),
);
}
Widget _buildButton(VoidCallback? onPressed, IconData icon, String label) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton.icon(
onPressed: onPressed,
icon: Icon(icon),
label: Text(label),
),
);
}
Widget _buildAppSwitch(BuildContext context, BtnBuilder btnBuilder) {
return btnBuilder(
() => Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const MyCupertinoApp()),
),
Icons.apple,
'Cupertino',
);
}
}
typedef BtnBuilder = Widget Function(VoidCallback? onPressed, IconData icon, String label);
Widget buildBody(
BuildContext context,
BtnBuilder btnBuilder,
Function(BuildContext context, BtnBuilder builder) buildAppSwitch,
List<AppTheme> themes,
) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 40.0),
child: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Wrap(
alignment: WrapAlignment.center,
children: buildFeatures(context, btnBuilder),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 40.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildAppSwitch(context, btnBuilder),
],
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: buildThemes(context, btnBuilder, themes),
),
],
),
),
),
);
}
List<Widget> buildFeatures(BuildContext context, BtnBuilder btnBuilder) {
final ThemeService service = ThemeProvider.of(context);
return [
btnBuilder(service.light, Icons.light_mode, 'light'),
btnBuilder(service.dark, Icons.dark_mode, 'dark'),
btnBuilder(service.system, Icons.settings, 'system'),
btnBuilder(service.toggle, service.isDark ? Icons.toggle_off : Icons.toggle_on, 'toggle'),
];
}
List<Widget> buildThemes(BuildContext context, BtnBuilder btnBuilder, List<AppTheme> themes) {
final ThemeService service = ThemeProvider.of(context);
return [
Row(
mainAxisSize: MainAxisSize.min,
children: [
btnBuilder(service.previous, Icons.skip_previous, 'previous'),
btnBuilder(service.next, Icons.skip_next, 'next'),
],
),
const SizedBox(height: 50,),
Column(
children: themes.map((theme) => btnBuilder(
() => ThemeProvider.of(context).index = themes.indexOf(theme),
(themes.indexOf(theme) == ThemeProvider.of(context).index)
? Icons.keyboard_double_arrow_right
: Icons.keyboard_arrow_right_outlined,
'Theme ${themes.indexOf(theme)} - ${theme.name}',
)).toList(),
),
];
}
更多关于Flutter主题管理插件x_theme_provider的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复