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

Flutter主题适配需求:默认跟随系统明暗模式,支持手动切换

解决方案:让Flutter应用启动时优先遵循系统主题,同时保留手动切换功能

下面分步骤修改你已有的代码:

1. 添加持久化依赖(若未添加)

要记住用户的手动切换设置,需用shared_preferences做本地存储,在pubspec.yaml的dependencies中添加:

shared_preferences: ^2.2.2

执行flutter pub get完成依赖安装。

2. 更新ThemeProvider逻辑

修改theme_provider.dart,让它初始化时优先读取用户保存的主题,无保存记录则跟随系统当前明暗模式,同时持久化用户的切换操作:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'theme.dart';

class ThemeProvider extends ChangeNotifier {
  ThemeMode _themeMode;

  ThemeProvider() {
    _initTheme();
  }

  // 初始化主题:优先读本地保存设置,无则用系统主题
  Future<void> _initTheme() async {
    final prefs = await SharedPreferences.getInstance();
    final savedTheme = prefs.getString('theme_mode');

    if (savedTheme != null) {
      _themeMode = savedTheme == 'light' ? ThemeMode.light : ThemeMode.dark;
    } else {
      // 获取系统当前明暗模式
      final systemBrightness = WidgetsBinding.instance.window.platformBrightness;
      _themeMode = systemBrightness == Brightness.light ? ThemeMode.light : ThemeMode.dark;
    }
    notifyListeners();
  }

  ThemeMode get themeMode => _themeMode;

  // 切换主题并保存到本地
  Future<void> toggleTheme() async {
    _themeMode = _themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('theme_mode', _themeMode == ThemeMode.light ? 'light' : 'dark');
    notifyListeners();
  }

  // 可选:添加重置为系统主题的方法
  Future<void> resetToSystem() async {
    final systemBrightness = WidgetsBinding.instance.window.platformBrightness;
    _themeMode = systemBrightness == Brightness.light ? ThemeMode.light : ThemeMode.dark;
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove('theme_mode');
    notifyListeners();
  }
}

3. 调整main.dart集成

确保MaterialApp正确使用Provider提供的主题模式:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'theme.dart';
import 'theme_provider.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => ThemeProvider(),
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    final themeProvider = Provider.of<ThemeProvider>(context);
    return MaterialApp(
      title: 'Your App',
      theme: LightMode, // 你的亮主题配置
      darkTheme: DarkMode, // 你的暗主题配置
      themeMode: themeProvider.themeMode, // 关键:绑定Provider中的主题模式
      home: const YourHomePage(),
    );
  }
}

核心逻辑说明

  • 首次启动:应用自动检测系统明暗模式,匹配对应的主题。
  • 用户手动切换后:新主题会被保存到本地,下次启动直接使用用户选择的主题,不再跟随系统(除非调用resetToSystem重置)。
  • 若你使用的是Flutter 3.0+版本,在Widget树内获取系统亮度也可以用View.of(context).platformDispatcher.platformBrightness,但初始化阶段(Widget树之外)用WidgetsBinding.instance.window.platformBrightness更稳妥。

内容的提问来源于stack exchange,提问作者Cedric Valentin Piehl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:21:00