Flutter动态主题切换插件dynamic_themes的使用
Flutter动态主题切换插件dynamic_themes的使用
dynamic_themes
是一个用于在Flutter应用中实现多主题动态切换的插件。它允许用户从多个预定义的主题中选择,并且能够在运行时动态地更新所选主题,同时支持跨应用重启持久化保存所选主题。
动态更改多个主题
该插件允许你为用户提供多个可选主题。主题可以在应用程序运行期间动态更新,并且会将选定的主题保存下来,在下次启动应用时自动恢复。
开始使用
请按照 官方安装指南 来添加依赖并配置你的项目。
使用方法
定义主题集合
你可以定义任意数量的主题,并为每个主题分配一个唯一的 int
类型ID。推荐创建一个包含静态常量整数的类来关联名称与ID值:
class AppThemes {
static const int LightBlue = 0;
static const int LightRed = 1;
static const int Dark = 2;
// 可以根据需要添加更多主题
}
final themeCollection = ThemeCollection(
themes: {
AppThemes.LightBlue: ThemeData(primarySwatch: Colors.blue),
AppThemes.LightRed: ThemeData(primarySwatch: Colors.red),
AppThemes.Dark: ThemeData.dark(),
},
fallbackTheme: ThemeData.light(), // 可选的默认主题
);
包装MaterialApp
接下来,用 DynamicTheme
小部件包装你的 MaterialApp
:
return DynamicTheme(
themeCollection: themeCollection,
defaultThemeId: AppThemes.LightBlue, // 可选,默认主题ID为0
builder: (context, theme) {
return MaterialApp(
title: 'dynamic_themes example',
theme: theme,
home: HomePage(title: 'dynamic_themes example app'),
);
}
);
切换主题
在应用中的任何地方,只要拥有 BuildContext
,就可以通过以下方式设置或切换主题:
DynamicTheme.of(context).setTheme(AppThemes.LightRed);
这将自动通过 shared_preferences
插件保存主题ID,确保下次启动应用时能够正确恢复主题。
获取当前主题信息
你可以像往常一样通过 Theme.of(context)
获取当前主题,也可以直接通过 DynamicTheme.of(context).theme
获取。若要获取当前主题的ID(例如用于构建UI选择器),可以调用:
final themeId = DynamicTheme.of(context).themeId;
示例代码
下面是一个完整的示例应用,演示了如何实现四个不同主题之间的切换功能:
import 'package:dynamic_themes/dynamic_themes.dart';
import 'package:flutter/material.dart';
void main() {
runApp(DynamicThemesExampleApp());
}
/// 应用的主题。
/// 此类仅用于将可读名称与整数主题ID关联起来。
class AppThemes {
static const int LightBlue = 0;
static const int LightRed = 1;
static const int DarkBlue = 2;
static const int DarkRed = 3;
static String toStr(int themeId) {
switch (themeId) {
case LightBlue:
return "Light Blue";
case LightRed:
return "Light Red";
case DarkBlue:
return "Dark Blue";
case DarkRed:
return "Dark Red";
default:
return "Unknown";
}
}
}
class DynamicThemesExampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final dark = ThemeData.dark();
final darkButtonTheme = dark.buttonTheme.copyWith(buttonColor: Colors.grey[700]);
final darkFABTheme = dark.floatingActionButtonTheme;
final themeCollection = ThemeCollection(
themes: {
AppThemes.LightBlue: ThemeData(primarySwatch: Colors.blue),
AppThemes.LightRed: ThemeData(primarySwatch: Colors.red),
AppThemes.DarkBlue: dark.copyWith(
accentColor: Colors.blue,
buttonTheme: darkButtonTheme,
floatingActionButtonTheme: darkFABTheme.copyWith(backgroundColor: Colors.blue)),
AppThemes.DarkRed: ThemeData.from(colorScheme: ColorScheme.dark(primary: Colors.red, secondary: Colors.red)),
}
);
return DynamicTheme(
themeCollection: themeCollection,
defaultThemeId: AppThemes.LightBlue,
builder: (context, theme) {
return MaterialApp(
title: 'dynamic_themes example',
theme: theme,
home: HomePage(title: 'dynamic_themes example app'),
);
}
);
}
}
class HomePage extends StatefulWidget {
final String title;
const HomePage({Key? key, required this.title}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int dropdownValue = 0;
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
dropdownValue = DynamicTheme.of(context)!.themeId;
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(children: [
Padding(
padding: const EdgeInsets.only(top: 24, bottom: 12),
child: Text('Select your theme here:'),
),
DropdownButton(
icon: Icon(Icons.arrow_downward),
value: dropdownValue,
items: [
DropdownMenuItem(
value: AppThemes.LightBlue,
child: Text(AppThemes.toStr(AppThemes.LightBlue)),
),
DropdownMenuItem(
value: AppThemes.LightRed,
child: Text(AppThemes.toStr(AppThemes.LightRed)),
),
DropdownMenuItem(
value: AppThemes.DarkBlue,
child: Text(AppThemes.toStr(AppThemes.DarkBlue)),
),
DropdownMenuItem(
value: AppThemes.DarkRed,
child: Text(AppThemes.toStr(AppThemes.DarkRed)),
)
],
onChanged: (dynamic themeId) async {
await DynamicTheme.of(context)!.setTheme(themeId);
setState(() {
dropdownValue = themeId;
});
}
),
Container(
margin: EdgeInsets.all(20),
width: 100,
height: 100,
color: theme.primaryColor,
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Container in primary color and primary text theme',
textAlign: TextAlign.center,
style: Theme.of(context).primaryTextTheme.bodyText2
),
),
)
),
Container(
margin: EdgeInsets.all(20),
width: 100,
height: 100,
color: theme.accentColor,
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Container in accent color and with accent text theme',
textAlign: TextAlign.center,
style: Theme.of(context).accentTextTheme.bodyText2),
)),
),
ElevatedButton(
onPressed: () {},
child: Text('Elevated Button'),
),
],
)
),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
BottomNavigationBarItem(icon: Icon(Icons.notifications), label: "Notifications"),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () { },
child: Icon(Icons.add),
),
);
}
}
以上就是关于 dynamic_themes
插件的基本介绍和使用示例。如果你有任何问题或者建议,欢迎访问 GitHub Issues 提交反馈。
更多关于Flutter动态主题切换插件dynamic_themes的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter动态主题切换插件dynamic_themes的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用dynamic_themes
插件来实现动态主题切换的一个示例代码。dynamic_themes
插件允许你在运行时更改应用程序的主题(如亮色主题和暗色主题)。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加dynamic_themes
依赖:
dependencies:
flutter:
sdk: flutter
dynamic_themes: ^1.0.0 # 请确保使用最新版本
然后运行flutter pub get
来获取依赖。
2. 配置主题
在lib
目录下创建一个新的文件themes.dart
,用于定义亮色和暗色主题:
import 'package:flutter/material.dart';
// 亮色主题
final lightTheme = ThemeData(
brightness: Brightness.light,
primaryColor: Colors.blue,
accentColor: Colors.teal,
backgroundColor: Colors.white,
textTheme: TextTheme(
bodyText1: TextStyle(color: Colors.black),
),
// 其他主题配置...
);
// 暗色主题
final darkTheme = ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.blueGrey,
accentColor: Colors.lightBlueAccent,
backgroundColor: Colors.grey[900],
textTheme: TextTheme(
bodyText1: TextStyle(color: Colors.white),
),
// 其他主题配置...
);
// 主题列表
final List<ThemeData> themes = [lightTheme, darkTheme];
3. 设置应用
在main.dart
中,使用DynamicTheme
插件来管理主题切换:
import 'package:flutter/material.dart';
import 'package:dynamic_themes/dynamic_themes.dart';
import 'themes.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DynamicTheme(
defaultBrightness: Brightness.light, // 默认亮度
themes: themes, // 主题列表
themedWidgetBuilder: (context, theme) {
return MaterialApp(
title: 'Flutter Dynamic Theme Demo',
theme: theme,
home: HomeScreen(),
);
},
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
bool isDarkMode = false;
void toggleTheme() {
setState(() {
isDarkMode = !isDarkMode;
DynamicTheme.of(context).setBrightness(
isDarkMode ? Brightness.dark : Brightness.light,
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dynamic Theme Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Current Theme: ${isDarkMode ? 'Dark' : 'Light'}',
style: TextStyle(fontSize: 24),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: toggleTheme,
child: Text('Toggle Theme'),
),
],
),
),
);
}
}
4. 运行应用
现在你可以运行你的Flutter应用,你应该能够看到一个带有主题切换按钮的页面。点击按钮将切换亮色和暗色主题。
这个示例展示了如何使用dynamic_themes
插件来动态切换Flutter应用的主题。你可以根据需要进一步自定义和扩展主题配置。