是什么
在 Flutter 里,切换主题有几种常见方式:
- 用
ThemeMode.light
/ThemeMode.dark
/ThemeMode.system
手动管理; - 自己写
SharedPreferences
来保存用户选择; - 每次
setState
改ThemeData
。
但是这样写会有些麻烦:
需要自己存储用户选择(比如存在本地);
需要自己封装切换逻辑。
所以 adaptive_theme
就出现了,帮你一站式解决。
adaptive_theme
是 Flutter 上的一个第三方库,主要用来 方便管理亮色 / 暗色 / 系统主题模式,并且支持 持久化存储(保存用户选择,下次打开还能记住)。
- 提供 亮色主题 和 暗色主题 的定义;
- 提供 跟随系统 的选项;
- 内置 本地存储(用
SharedPreferences
记住选择); - 提供简单的 API:随时在代码里切换主题。
安装
flutter pub add adaptive_theme
核心 API
AdaptiveTheme.of(context).setLight()
→ 切换亮色
AdaptiveTheme.of(context).setDark()
→ 切换暗色
AdaptiveTheme.of(context).setSystem()
→ 跟随系统
AdaptiveTheme.getThemeMode()
→ 获取上次保存的模式(异步)
**“上一次保存的模式”**指的是 用户上一次在应用里选择的主题模式,它会被
adaptive_theme
自动存储在本地(一般是SharedPreferences
)。
- 用户第一次打开 App,默认是 跟随系统(
AdaptiveThemeMode.system
)。- 用户在设置页面里点了 切换到暗色模式 → 这时
adaptive_theme
会调用SharedPreferences
把"dark"
存起来。- 你关掉 App 再重新打开 →
AdaptiveTheme.getThemeMode()
会去本地读取"dark"
,然后恢复成暗色模式,而不是又回到默认的系统模式。
使用案例
- 恢复上次用户选择:
AdaptiveTheme.getThemeMode()
- 创建
AdaptiveTheme
- 通过
AdaptiveTheme
的builder
创建MaterialApp
或者GetMaterialApp
- 设置主题模型
import 'package:flutter/material.dart';
import 'package:adaptive_theme/adaptive_theme.dart';
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});
@override
Widget build(BuildContext context) {
return AdaptiveTheme(
light: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
),
dark: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: Brightness.dark,
),
),
// debugShowFloatingThemeButton: true, // 显示主题按钮
// 初始主题模式: 如果用户之前选择过主题(savedThemeMode),则使用用户选择的主题
initial: savedThemeMode ?? AdaptiveThemeMode.system, // 默认跟随系统
builder: (theme, darkTheme) => MaterialApp(
title: 'Adaptive Theme Demo',
theme: theme,
darkTheme: darkTheme,
home: const HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Adaptive Theme Demo")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
child: const Text("切换到亮色"),
onPressed: () => AdaptiveTheme.of(context).setLight(),
),
ElevatedButton(
child: const Text("切换到暗色"),
onPressed: () => AdaptiveTheme.of(context).setDark(),
),
ElevatedButton(
child: const Text("跟随系统"),
onPressed: () => AdaptiveTheme.of(context).setSystem(),
),
],
),
),
);
}
}
系统默认的是亮色,当我点击切换到暗色的时候,系统就会切换暗色主题。如果这个时候我关闭APP(在vscode里面就是关闭程序),接着再打开APP(在VScode就是运行程序),这个时候APP还是暗色。