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

如何利用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 01:22:36