You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 12:57:44