如何在Flutter中通过Theme Provider将可选列表主题设为默认主题
用Theme Provider实现主题切换并设置默认主题
先提个小修正:你提供的ThemeData生成代码里,cards[chosenTheme].themes应该改成themes[chosenTheme]——因为你定义的是全局的themes列表,并非嵌套在cards结构里。
下面是具体实现步骤:
1. 添加Provider依赖
在项目的pubspec.yaml中添加provider包:
dependencies: flutter: sdk: flutter provider: ^6.1.1 # 可替换为最新版本
执行flutter pub get完成依赖安装。
2. 创建主题状态管理类
新建theme_provider.dart文件,写一个继承自ChangeNotifier的类,用来管理主题索引、生成对应ThemeData:
import 'package:flutter/material.dart'; import '你存放ThemeModel的文件路径.dart'; class ThemeProvider extends ChangeNotifier { // 默认选中第一个主题 int chosenTheme = 0; // 获取当前主题的ThemeData ThemeData get currentTheme { final themeModel = themes[chosenTheme]; return ThemeData( fontFamily: 'estedad', useMaterial3: true, colorScheme: chosenTheme <= 2 ? ColorScheme.light( surface: themeModel.surface, primary: themeModel.primary, secondary: themeModel.secondary, onSurface: themeModel.onSurface, ) : ColorScheme.dark( surface: themeModel.surface, primary: themeModel.primary, secondary: themeModel.secondary, onSurface: themeModel.onSurface, ), ); } // 切换主题的方法 void setTheme(int index) { chosenTheme = index; notifyListeners(); // 通知UI更新主题 } }
3. 在主入口配置Provider
修改main.dart,用ChangeNotifierProvider包裹MaterialApp,让整个应用能访问主题状态:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'theme_provider.dart'; import '你的主题选择页面路径.dart'; void main() { runApp( ChangeNotifierProvider( create: (context) => ThemeProvider(), child: const MyApp(), ), ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: '主题切换示例', // 从Provider获取当前主题 theme: Provider.of<ThemeProvider>(context).currentTheme, home: const ThemeSelectionPage(), // 主题选择页面 ); } }
4. 实现主题选择UI
创建theme_selection_page.dart,展示主题列表供用户选择:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'theme_provider.dart'; import '你存放ThemeModel的文件路径.dart'; class ThemeSelectionPage extends StatelessWidget { const ThemeSelectionPage({super.key}); @override Widget build(BuildContext context) { final themeProvider = Provider.of<ThemeProvider>(context); return Scaffold( appBar: AppBar(title: const Text('选择主题')), body: ListView.builder( itemCount: themes.length, itemBuilder: (context, index) { final theme = themes[index]; return ListTile( title: Text('主题 ${index + 1}'), leading: Container( width: 40, height: 40, color: theme.surface, child: Center( child: Container( width: 20, height: 20, color: theme.primary, ), ), ), trailing: themeProvider.chosenTheme == index ? const Icon(Icons.check_circle, color: Colors.green) : const Icon(Icons.circle_outlined), onTap: () { themeProvider.setTheme(index); Navigator.pop(context); // 选择后返回上一页 }, ); }, ), ); } }
可选:持久化主题选择
如果需要让用户选择的主题在重启应用后保留,可以添加shared_preferences依赖,修改ThemeProvider:
import 'package:shared_preferences/shared_preferences.dart'; class ThemeProvider extends ChangeNotifier { int chosenTheme = 0; ThemeProvider() { _loadSavedTheme(); } // 加载本地保存的主题索引 Future<void> _loadSavedTheme() async { final prefs = await SharedPreferences.getInstance(); chosenTheme = prefs.getInt('chosen_theme') ?? 0; notifyListeners(); } // 切换并保存主题 Future<void> setTheme(int index) async { chosenTheme = index; final prefs = await SharedPreferences.getInstance(); await prefs.setInt('chosen_theme', index); notifyListeners(); } // ... 其他代码不变 }
内容的提问来源于stack exchange,提问作者abdollah
相关产品推荐
相关产品推荐

