如何在Flutter设置页面实现3种主题切换功能(当前仅main.dart可切换)
跨页面主题切换实现方案
要把主题切换功能迁移至设置页面,核心是让主题状态能在全局范围内共享,以下是具体实现步骤:
1. 抽离主题状态管理类
创建独立的主题状态管理类,负责保存当前主题并提供切换方法,这里用ChangeNotifier实现状态通知:
import 'package:flutter/material.dart'; enum AppTheme { LightTheme, DarkTheme, CustomTheme; } extension AppThemeData on AppTheme { ThemeData get data { switch (this) { case AppTheme.DarkTheme: return ThemeData.dark(); case AppTheme.CustomTheme: return ThemeData( useMaterial3: true, colorScheme: ColorScheme.fromSwatch().copyWith( secondary: Colors.deepPurple, ), ); case AppTheme.LightTheme: default: return ThemeData.light(); } } } class ThemeProvider extends ChangeNotifier { AppTheme _currentTheme = AppTheme.LightTheme; AppTheme get currentTheme => _currentTheme; void setTheme(AppTheme theme) { _currentTheme = theme; notifyListeners(); // 通知所有监听组件更新主题 } }
2. 在根组件注入状态管理
修改main.dart,通过ChangeNotifierProvider将主题状态注入到整个应用上下文中:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'theme_provider.dart'; import 'settings_page.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 Consumer<ThemeProvider>( builder: (context, themeProvider, child) { return MaterialApp( title: 'Material App', theme: themeProvider.currentTheme.data, home: const HomePage(), routes: { '/settings': (context) => const SettingsPage(), }, ); }, ); } } class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("首页")), body: Center( child: ElevatedButton( onPressed: () => Navigator.pushNamed(context, '/settings'), child: const Text("前往设置页面切换主题"), ), ), ); } }
3. 在设置页面实现主题切换
创建settings_page.dart,通过Provider获取主题状态,添加切换按钮:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'theme_provider.dart'; class SettingsPage extends StatelessWidget { const SettingsPage({super.key}); @override Widget build(BuildContext context) { final themeProvider = Provider.of<ThemeProvider>(context); return Scaffold( appBar: AppBar(title: const Text("设置")), body: Column( children: [ const Text("选择主题"), for (final theme in AppTheme.values) ElevatedButton( onPressed: () { themeProvider.setTheme(theme); Navigator.pop(context); // 可选:切换后返回首页 }, child: Text(theme.name), ) ], ), ); } }
核心逻辑说明
- 用
ChangeNotifierProvider实现全局状态共享,确保主题变更能同步到所有页面 - 通过
Consumer和Provider.of在组件中监听、获取主题状态 - 抽离主题相关的枚举、扩展和状态管理类,让代码结构更清晰
内容的提问来源于stack exchange,提问作者Leena Marie
相关产品推荐
相关产品推荐

