Flutter主题切换插件theme_patrol的使用
Flutter主题切换插件theme_patrol
的使用
theme_patrol
是一个强大的Flutter插件,用于管理应用程序的主题切换。它支持在不同主题模式(如亮色/暗色)之间切换,并且可以轻松地在多个预定义的主题之间切换。
特性
- 在亮色/暗色模式之间切换
- 切换多个主题
- 覆盖当前主题颜色
使用方法
基本用法
import 'package:flutter/material.dart';
import 'package:theme_patrol/theme_patrol.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ThemePatrol(
initialMode: ThemeMode.system,
light: ThemeData(
brightness: Brightness.light,
colorSchemeSeed: Colors.purple,
),
dark: ThemeData(
brightness: Brightness.dark,
colorSchemeSeed: Colors.purple,
toggleableActiveColor: Colors.purple,
),
builder: (context, theme, child) {
return MaterialApp(
title: 'ThemePatrol',
theme: theme.data,
darkTheme: theme.darkData,
themeMode: theme.mode,
home: HomePage(),
);
},
);
}
}
消费者模式
ThemeController theme = ThemePatrol.of(context);
ThemeConsumer(
builder: (context, theme, child) {
return Container();
},
);
详细配置
ThemeProvider(
controller: ThemeController(
initialMode: ThemeMode.system,
light: ThemeData(
brightness: Brightness.light,
colorSchemeSeed: Colors.purple,
),
// 其他配置...
),
child: ThemeConsumer(
builder: (context, theme, child) {
return MaterialApp(
title: 'ThemePatrol',
theme: theme.data,
darkTheme: theme.darkData,
themeMode: theme.mode,
home: HomePage(),
);
},
),
);
Provider 集成
import 'package:provider/provider.dart';
ChangeNotifierProvider(
create: (_) => ThemeController(
initialMode: ThemeMode.system,
light: ThemeData(
brightness: Brightness.light,
colorSchemeSeed: Colors.purple,
),
// 其他配置...
),
child: ...,
);
// 获取主题控制器
ThemeController theme = Provider.of<ThemeController>(context, listen: true);
ThemeController theme = context.watch<ThemeController>();
ThemeController theme = context.read<ThemeController>();
ThemeMode mode = context.select((ThemeController theme) => theme.mode);
使用场景
仅在亮色/暗色模式之间切换
ThemePatrol(
initialMode: ThemeMode.system,
light: ThemeData(
brightness: Brightness.light,
colorSchemeSeed: Colors.purple,
),
dark: ThemeData(
brightness: Brightness.dark,
colorSchemeSeed: Colors.purple,
toggleableActiveColor: Colors.purple,
),
builder: (context, theme, child) {
return MaterialApp(
title: 'ThemePatrol',
theme: theme.data,
darkTheme: theme.darkData,
themeMode: theme.mode,
home: Scaffold(
appBar: AppBar(
title: Text(ThemePatrol.of(context).mode.toString()),
actions: [
ThemeConsumer(
builder: (context, theme, child) {
return Switch(
value: theme.isDarkMode,
onChanged: (selected) {
if (selected) {
theme.toDarkMode();
} else {
theme.toLightMode();
}
},
);
},
),
],
),
),
);
},
);
多个主题,无暗色模式
ThemePatrol(
initialTheme: 'amber',
themes: {
'purple': ThemeConfig.fromColor(Colors.purple),
'pink': ThemeConfig.fromColor(Colors.pink),
'amber': ThemeConfig.fromColor(Colors.amber),
'elegant': ThemeConfig(data: ThemeData()),
},
builder: (context, theme, child) {
return MaterialApp(
title: 'ThemePatrol',
theme: theme.data,
home: Scaffold(
appBar: AppBar(
title: Text(ThemePatrol.of(context).selected),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ThemeConsumer(
builder: (context, theme, _) {
return Wrap(
spacing: 5,
children: theme.availableEntries
.map((e) => ActionChip(
label: Text(e.key),
onPressed: () => theme.select(e.key),
avatar: CircleAvatar(
backgroundColor:
e.value.colorSchemeOf(context).primary,
),
))
.toList(),
);
},
),
],
),
),
),
);
},
);
多个主题,带暗色模式
ThemePatrol(
initialTheme: 'amber',
initialMode: ThemeMode.system,
themes: {
'purple': ThemeConfig.fromColor(Colors.purple),
'pink': ThemeConfig.fromColor(Colors.pink),
'amber': ThemeConfig.fromColor(Colors.amber),
'basic': ThemeConfig(data: ThemeData()),
'pro': ThemeConfig(data: ThemeData(), dark: ThemeData()),
'premium': ThemeConfig(light: ThemeData(), dark: ThemeData()),
},
builder: (context, theme, _) {
return MaterialApp(
title: 'ThemePatrol',
theme: theme.data,
darkTheme: theme.darkData,
themeMode: theme.mode,
home: Scaffold(
appBar: AppBar(
title: Text(ThemePatrol.of(context).selected),
actions: [
ThemeConsumer(
builder: (context, theme, _) {
return Switch(
value: theme.isDarkMode,
onChanged: (selected) {
if (selected) {
theme.toDarkMode();
} else {
theme.toLightMode();
}
},
);
},
),
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ThemeConsumer(
builder: (context, theme, _) {
return Wrap(
spacing: 5,
children: theme.available.entries
.map((e) => ActionChip(
label: Text(e.key),
onPressed: () => theme.select(e.key),
avatar: CircleAvatar(
backgroundColor:
e.value.colorSchemeOf(context).primary,
),
))
.toList(),
);
},
),
],
),
),
),
);
},
);
完整示例 Demo
以下是一个完整的示例,展示了如何使用 theme_patrol
插件来实现主题切换功能:
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:theme_patrol/theme_patrol.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ThemePatrol(
onAvailableChanged: (_) => log('available themes changed'),
onThemeChanged: (theme) => log('theme changed to ${theme.selected}'),
onModeChanged: (theme) => log('theme mode changed to ${theme.mode.name}'),
onColorChanged: (theme) =>
log('theme color changed to ${theme.color.toString()}'),
onChanged: (theme) => log('value changed'),
themes: {
'basic': ThemeConfig.fromColor(Colors.purple),
'pro': ThemeConfig.fromColor(Colors.red),
'premium': ThemeConfig.fromColor(Colors.amber),
},
light: ThemeData.light(),
dark: ThemeData.dark(),
builder: (context, theme, _) {
return MaterialApp(
title: 'ThemePatrol Example',
theme: theme.data,
darkTheme: theme.darkData,
themeMode: theme.mode,
home: const MyHomePage(title: 'ThemePatrol Example'),
builder: theme.bootstrap(),
);
},
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
MyHomePageState createState() => MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(0, 45, 0, 25),
child: Center(
child: Text(
'ThemePatrol',
style: TextStyle(
fontSize: 36,
fontWeight: FontWeight.bold,
letterSpacing: -2,
),
),
),
),
ThemeConsumer(
builder: (context, theme, _) {
return Column(
children: [
ElevatedButton.icon(
onPressed: () => theme.toggleMode(),
icon: AnimatedSwitcher(
duration: const Duration(milliseconds: 200),
child: Icon(
theme.modeIcon,
key: ValueKey(theme.mode),
),
),
label: Text('${theme.mode.name.toUpperCase()} MODE'),
),
const SizedBox(height: 10),
OutlinedButton(
onPressed: () => theme.resetMode(),
child: const Text('Reset to Initial Mode'),
),
],
);
},
),
const SizedBox(height: 30),
ThemeConsumer(
builder: (context, theme, _) {
return Wrap(
spacing: 5,
children: theme.availableEntries
.map((e) => FilterChip(
label: Text(e.key),
onSelected: (_) => theme.select(e.key),
selected: theme.selected == e.key,
checkmarkColor: Colors.white,
avatar: CircleAvatar(
backgroundColor:
e.value.colorSchemeOf(context).primary,
),
))
.toList(),
);
},
),
const SizedBox(height: 20),
Wrap(
spacing: 5,
children: [
TextButton(
onPressed: () => ThemePatrol.of(context).selectPrev(),
child: const Text('Prev Theme'),
),
ElevatedButton(
onPressed: () => ThemeProvider.of(context).resetTheme(),
child: const Text('Reset to Initial Theme'),
),
TextButton(
onPressed: () => ThemeProvider.of(context).selectNext(),
child: const Text('Next Theme'),
),
],
),
const SizedBox(height: 10),
OutlinedButton(
onPressed: () => ThemePatrol.of(context).selectRandom(),
child: const Text('Random Theme'),
),
const SizedBox(height: 30),
const Text(
'Override Theme Color',
style: TextStyle(fontWeight: FontWeight.w400),
),
const SizedBox(height: 10),
ThemeConsumer(builder: (context, theme, _) {
return Container(
width: 200,
alignment: Alignment.center,
child: GridView.builder(
shrinkWrap: true,
itemCount: Colors.primaries.length,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: 2,
crossAxisSpacing: 2,
crossAxisCount: 6,
),
itemBuilder: (_, i) {
final color = Colors.primaries[i];
return Card(
color: color,
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: () => theme.toColor(color),
child: AnimatedCheckmark(
weight: 4,
color: Colors.white70,
active: color == theme.color,
),
),
);
},
),
);
}),
const SizedBox(height: 10),
TextButton(
onPressed: () => ThemePatrol.of(context).resetColor(),
child: const Text('Reset Color to Theme Color'),
),
const SizedBox(height: 30),
ElevatedButton(
onPressed: () => ThemePatrol.of(context).reset(),
child: const Text('Reset All to Initial Values'),
)
],
),
),
),
);
}
}
通过这个完整的示例,你可以了解如何使用 theme_patrol
插件来实现丰富的主题切换功能。
更多关于Flutter主题切换插件theme_patrol的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter主题切换插件theme_patrol的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是如何在Flutter应用中使用theme_patrol
插件来实现主题切换的示例代码。theme_patrol
是一个用于Flutter的插件,它简化了主题切换的实现。假设你已经将theme_patrol
添加到你的pubspec.yaml
文件中并运行了flutter pub get
。
1. 添加依赖
首先,确保你的pubspec.yaml
文件中包含theme_patrol
依赖:
dependencies:
flutter:
sdk: flutter
theme_patrol: ^最新版本号 # 替换为最新版本号
2. 设置主题数据
在你的main.dart
文件中,定义两个主题(例如,亮色主题和暗色主题):
import 'package:flutter/material.dart';
import 'package:theme_patrol/theme_patrol.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ThemePatrol(
// 初始主题
initialThemeMode: ThemeMode.system, // 可以是 ThemeMode.light, ThemeMode.dark, 或 ThemeMode.system
themes: {
ThemeMode.light: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.blue,
// 其他主题设置
),
ThemeMode.dark: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.deepPurple,
// 其他主题设置
),
},
builder: (context, theme) {
return MaterialApp(
title: 'Flutter Theme Patrol Demo',
theme: theme,
home: MyHomePage(),
);
},
);
}
}
3. 创建主题切换按钮
在你的MyHomePage
中,添加一个按钮来切换主题:
import 'package:flutter/material.dart';
import 'package:theme_patrol/theme_patrol.dart';
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemePatrolController themePatrolController = ThemePatrol.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Theme Patrol Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Current Theme Mode: ${themePatrolController.themeMode == ThemeMode.light ? 'Light' : 'Dark'}',
style: TextStyle(fontSize: 24),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
themePatrolController.setThemeMode(
themePatrolController.themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light,
);
},
child: Text('Switch Theme'),
),
],
),
),
);
}
}
4. 完整代码
以下是完整的main.dart
代码,包含上述所有部分:
import 'package:flutter/material.dart';
import 'package:theme_patrol/theme_patrol.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ThemePatrol(
initialThemeMode: ThemeMode.system,
themes: {
ThemeMode.light: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.blue,
),
ThemeMode.dark: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.deepPurple,
),
},
builder: (context, theme) {
return MaterialApp(
title: 'Flutter Theme Patrol Demo',
theme: theme,
home: MyHomePage(),
);
},
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemePatrolController themePatrolController = ThemePatrol.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Theme Patrol Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Current Theme Mode: ${themePatrolController.themeMode == ThemeMode.light ? 'Light' : 'Dark'}',
style: TextStyle(fontSize: 24),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
themePatrolController.setThemeMode(
themePatrolController.themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light,
);
},
child: Text('Switch Theme'),
),
],
),
),
);
}
}
这个示例展示了如何使用theme_patrol
插件在Flutter应用中实现主题切换功能。你可以根据需要进一步自定义和扩展这些代码。