Flutter动态主题切换插件dynamik_theme的使用
Flutter动态主题切换插件dynamik_theme的使用
插件简介
dynamik_theme
是一个Flutter插件,它可以帮助你轻松设置主题模式或自定义颜色。该插件支持在支持的平台上使用动态颜色,并且可以通过你选择的存储方式持久化主题状态。
主要功能
- Light Mode:基于浅色方案的主题。
- Dark Mode:基于深色方案的主题。
- System Mode:根据系统设置自动切换浅色或深色主题。
- Dynamic Color:使用
dynamic_color
从设备中自动获取颜色(不支持iOS)。 - Custom Color:设置任何你想要的颜色。
使用方法
1. 设置存储
为了持久化主题状态,你需要实现 ThemeStorage
接口。以下是一个使用 Hive 作为存储的示例:
class HiveStorage extends ThemeStorage {
final box = Hive.box<String>(_boxName);
final key = 'theme';
@override
Future<void> delete() async {
await box.clear();
}
@override
ThemeState? read() {
final res = box.get(key);
if (res == null) return null;
return ThemeState.fromJson(res);
}
@override
Future<void> write(ThemeState state) async {
await box.put(key, state.toJson());
}
}
你也可以使用 SharedPreferences
或其他数据库来实现 ThemeStorage
。
在 main.dart
中初始化存储:
void main() async {
// 初始化 Hive
await Hive.initFlutter();
await Hive.openBox<String>(_boxName);
// 设置 ThemeStorage。如果不设置,默认使用 InMemoryThemeStorage。
ThemeConfig.storage = HiveStorage();
runApp(const MyApp());
}
2. 使用 DynamikTheme
在 MyApp
中使用 DynamikTheme
来配置主题:
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return DynamikTheme(
config: ThemeConfig(
useMaterial3: true,
// 你可以从 https://m3.material.io/theme-builder#/custom 生成颜色方案
lightScheme: ColorScheme.fromSeed(seedColor: Colors.red),
darkScheme: ColorScheme.fromSeed(
seedColor: Colors.red,
brightness: Brightness.dark,
),
defaultThemeState: SimpleThemeType.dynamik.themeState,
builder: (themeData) {
// 添加更多自定义配置
return themeData.copyWith(
appBarTheme: const AppBarTheme(centerTitle: true),
inputDecorationTheme: const InputDecorationTheme(
border: OutlineInputBorder(),
),
);
},
),
builder: (theme, darkTheme, themeMode) {
return MaterialApp(
themeMode: themeMode,
theme: theme,
darkTheme: darkTheme,
debugShowCheckedModeBanner: false,
home: const Home(),
);
},
);
}
}
3. 更新主题
你可以通过以下方式更新主题:
-
设置新的主题:
DynamikTheme.of(context).setTheme(themeState);
-
更改主题模式:
DynamikTheme.of(context).setThemeMode(ThemeMode.light); // 或 ThemeMode.dark, ThemeMode.system
-
设置动态颜色模式:
DynamikTheme.of(context).setDynamikColorMode(); // 自动从设备获取颜色(不支持iOS)
-
设置自定义颜色:
DynamikTheme.of(context).setCustomColorMode(color);
4. 示例代码
以下是一个完整的示例代码,展示了如何使用 dynamik_theme
插件来实现动态主题切换:
import 'dart:math';
import 'package:dynamik_theme/dynamik_theme.dart';
import 'package:flutter/material.dart';
import 'package:hive_flutter/adapters.dart';
const _boxName = 'theme-storage';
const _space = SizedBox(height: 16, width: 16);
final _colors = List.generate(
8,
(index) => Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0),
);
class HiveStorage extends ThemeStorage {
final box = Hive.box<String>(_boxName);
final key = 'theme';
@override
Future<void> delete() async {
await box.clear();
}
@override
ThemeState? read() {
final res = box.get(key);
if (res == null) return null;
return ThemeState.fromJson(res);
}
@override
Future<void> write(ThemeState state) async {
await box.put(key, state.toJson());
}
}
void main() async {
await Hive.initFlutter();
await Hive.openBox<String>(_boxName);
/// 设置 ThemeStorage。如果不设置,默认使用 InMemoryThemeStorage。
ThemeConfig.storage = HiveStorage();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return DynamikTheme(
config: ThemeConfig(
useMaterial3: true,
// 你可以从 https://m3.material.io/theme-builder#/custom 生成颜色方案
lightScheme: ColorScheme.fromSeed(seedColor: Colors.red),
darkScheme: ColorScheme.fromSeed(
seedColor: Colors.red,
brightness: Brightness.dark,
),
defaultThemeState: SimpleThemeType.dynamik.themeState,
builder: (themeData) {
return themeData.copyWith(
appBarTheme: const AppBarTheme(centerTitle: true),
inputDecorationTheme: const InputDecorationTheme(
border: OutlineInputBorder(),
),
);
},
),
builder: (theme, darkTheme, themeMode) {
return MaterialApp(
themeMode: themeMode,
theme: theme,
darkTheme: darkTheme,
debugShowCheckedModeBanner: false,
home: const Home(),
);
},
);
}
}
class Home extends StatelessWidget {
const Home({super.key});
@override
Widget build(BuildContext context) {
final themeState = DynamikTheme.of(context).themeState;
return Scaffold(
appBar: AppBar(
title: const Text('Dynamik Theme'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.create),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(8),
child: Column(
children: [
Center(
child: Text(
'SimpleThemeType:',
style: Theme.of(context).textTheme.titleMedium,
),
),
_space,
Wrap(
runSpacing: 10,
spacing: 10,
children: SimpleThemeType.values
.map((e) => InputChip(
label: Text(e.name),
selected: themeState == e.themeState,
onPressed: () {
DynamikTheme.of(context).setTheme(e.themeState);
},
))
.toList(),
),
_space,
_space,
Text(
'Custom Colors:',
style: Theme.of(context).textTheme.titleMedium,
),
_space,
Wrap(
runSpacing: 10,
spacing: 10,
children: ThemeMode.values
.map(
(e) => InputChip(
label: Text(e.name),
selected: themeState.themeMode == e,
onPressed: () {
DynamikTheme.of(context).setThemeMode(e);
},
),
)
.toList(),
),
_space,
Wrap(
runSpacing: 10,
spacing: 10,
children: ColorMode.values
.map(
(e) => InputChip(
label: Text(e.name),
selected: themeState.colorMode == e,
onPressed: e == ColorMode.dynamik
? () {
DynamikTheme.of(context).setDynamikColorMode();
}
: null,
),
)
.toList(),
),
_space,
Wrap(
spacing: 10,
runSpacing: 10,
key: const ValueKey('value'),
children: _colors.map((e) {
return GestureDetector(
onTap: () {
DynamikTheme.of(context).setCustomColorMode(e);
},
child: CircleAvatar(
backgroundColor: e,
),
);
}).toList(),
),
_space,
const Divider(),
_space,
Wrap(
runSpacing: 10,
spacing: 10,
children: [
TextButton(onPressed: () {}, child: const Text('TextButton')),
ElevatedButton.icon(
onPressed: () {},
icon: const Icon(Icons.image),
label: const Text('ElevatedButton'),
),
FilledButton(
onPressed: () {},
child: const Text('FilledButton'),
),
],
),
_space,
const TextField(),
_space,
const TextField(
decoration: InputDecoration(
border: UnderlineInputBorder(),
errorText: 'ErrorText',
),
),
_space,
CheckboxListTile(
title: const Text('CheckboxListTile'),
value: true,
onChanged: (_) {},
),
RadioListTile(
value: true,
groupValue: true,
onChanged: (_) {},
title: const Text('RadioListTile'),
),
],
),
),
);
}
}
5. 预定义的主题状态列表
你可以使用 SimpleThemeType
提供的预定义主题状态,或者创建自己的主题状态列表:
enum MyThemeType {
dynamik(ThemeState(
themeMode: ThemeMode.system,
colorMode: ColorMode.dynamik,
)),
light(ThemeState(themeMode: ThemeMode.light)),
dark(ThemeState(themeMode: ThemeMode.dark));
const MyThemeType(this.themeState);
final ThemeState themeState;
}
更多关于Flutter动态主题切换插件dynamik_theme的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter动态主题切换插件dynamik_theme的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter动态主题切换插件dynamik_theme
的示例代码。这个示例将展示如何集成dynamik_theme
插件并实现简单的主题切换功能。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加dynamik_theme
的依赖:
dependencies:
flutter:
sdk: flutter
dynamik_theme: ^latest_version # 请替换为实际的最新版本号
2. 导入插件并配置主题
在你的main.dart
文件中,导入dynamik_theme
并配置主题。
import 'package:flutter/material.dart';
import 'package:dynamik_theme/dynamik_theme.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DynamikTheme(
defaultThemeMode: ThemeMode.system, // 可以设置为 ThemeMode.light 或 ThemeMode.dark
themes: {
ThemeMode.light: lightTheme(),
ThemeMode.dark: darkTheme(),
},
child: MaterialApp(
title: 'Dynamik Theme Example',
themeMode: DynamikTheme.of(context).themeMode, // 使用 DynamikTheme 的 themeMode
theme: DynamikTheme.of(context).theme, // 使用 DynamikTheme 的 theme
darkTheme: DynamikTheme.of(context).darkTheme, // 使用 DynamikTheme 的 darkTheme
home: HomeScreen(),
),
);
}
// 定义 Light 主题
ThemeData lightTheme() {
return ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.blue,
// 其他主题配置
);
}
// 定义 Dark 主题
ThemeData darkTheme() {
return ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.blueGrey,
// 其他主题配置
);
}
}
3. 创建切换主题的按钮
在你的HomeScreen
中,创建一个按钮来切换主题。
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dynamik Theme Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Current Theme Mode: ${DynamikTheme.of(context).themeMode.toString()}',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
setState(() {
DynamikTheme.of(context).setThemeMode(
DynamikTheme.of(context).themeMode == ThemeMode.light
? ThemeMode.dark
: ThemeMode.light,
);
});
},
child: Text('Switch Theme'),
),
],
),
),
);
}
}
4. 运行应用
现在,你可以运行你的Flutter应用,应该能够看到一个按钮,点击该按钮可以在Light和Dark主题之间切换。
注意事项
- 确保你已经正确安装了Flutter和Dart环境。
- 插件的版本号可能会更新,请确保使用最新版本。
- 你可以根据需要进一步自定义主题,包括颜色、字体等。
以上示例展示了如何使用dynamik_theme
插件在Flutter应用中实现动态主题切换功能。希望这对你有所帮助!