如何利用Provider存储的值动态切换Flutter应用主题?
最快重构方案
1. 改造GlobalsProvider,添加主题版本控制
先在globals_provider.dart里定义主题版本枚举,新增对应变量和更新方法,确保状态变化时通知UI刷新:
// globals_provider.dart import 'package:flutter/material.dart'; // 限定主题版本仅有的两个可选值 enum ThemeVersion { v1, v2 } class GlobalsProvider extends ChangeNotifier { // 默认主题版本 ThemeVersion _themeVersion = ThemeVersion.v1; ThemeVersion get themeVersion => _themeVersion; // 更新主题版本并触发UI刷新 void setThemeVersion(ThemeVersion version) { _themeVersion = version; notifyListeners(); } }
2. 重构main.dart,实现动态主题切换
把GetMaterialApp嵌套进Consumer组件,这样就能监听GlobalsProvider的状态变化;同时把主题定义抽成方法,根据当前themeVersion返回对应主题:
import 'package:ats/providers/globals_provider.dart'; import 'package:ats/wrapper.dart'; import 'package:flutter/material.dart'; import 'package:get/get_navigation/src/root/get_material_app.dart'; import 'package:provider/provider.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); // 按主题版本返回对应ThemeData ThemeData _generateTheme(ThemeVersion version) { switch(version) { case ThemeVersion.v1: return ThemeData( useMaterial3: false, colorScheme: ColorScheme.fromSeed( seedColor: Colors.red, brightness: Brightness.dark, ), textTheme: TextTheme( displayLarge: const TextStyle( fontSize: 72, fontWeight: FontWeight.bold, ), ), ); case ThemeVersion.v2: return ThemeData( useMaterial3: false, colorScheme: ColorScheme.fromSeed( seedColor: Colors.blue, brightness: Brightness.light, ), textTheme: TextTheme( displayLarge: const TextStyle( fontSize: 72, fontWeight: FontWeight.w500, color: Colors.black87, ), ), ); } } @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => GlobalsProvider(), // 通过Consumer监听主题版本变化,实时更新主题 child: Consumer<GlobalsProvider>( builder: (context, globalsProvider, child) { return GetMaterialApp( title: 'My App', theme: _generateTheme(globalsProvider.themeVersion), home: const MyHomePage(title: 'My App'), ); }, ), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return const Wrapper(); } }
3. 主题切换调用示例
在任意子组件中,通过Provider获取GlobalsProvider实例,调用方法切换主题:
// 比如在Wrapper组件中添加切换按钮 Provider.of<GlobalsProvider>(context, listen: false) .setThemeVersion(ThemeVersion.v2);
这种方式改动量最小,仅调整了GetMaterialApp的层级,通过Consumer实现状态监听,同时用枚举保证themeVersion的合法性。
内容的提问来源于stack exchange,提问作者TheMortiestMorty
相关产品推荐
相关产品推荐

