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

Flutter暗黑模式切换后重启恢复问题求助(Provider+SharedPreferences)

问题分析与解决方案

你的代码核心问题是没有将用户选择的主题模式持久化存储:每次重启App时,ThemeProvider都会重新初始化,themeMode被重置为默认的ThemeMode.dark,导致重启后自动回到暗黑模式。

以下是具体修复步骤:


1. 添加本地存储依赖

在pubspec.yaml中加入shared_preferences(用于本地键值对存储):

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.5
  shared_preferences: ^2.2.2

执行flutter pub get安装依赖。


2. 修改ThemeProvider,加入持久化逻辑

更新ThemeProvider.dart,在初始化时读取本地存储的主题设置,切换主题时保存设置:

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

class ThemeProvider extends ChangeNotifier {
  ThemeMode themeMode = ThemeMode.dark;

  // 构造函数中加载本地保存的主题
  ThemeProvider() {
    _loadSavedTheme();
  }

  bool get isDarkMode => themeMode == ThemeMode.dark;

  // 从本地存储读取主题设置
  Future<void> _loadSavedTheme() async {
    final prefs = await SharedPreferences.getInstance();
    // 默认值为true(暗黑模式),和初始设置保持一致
    final isDark = prefs.getBool('isDarkMode') ?? true;
    themeMode = isDark ? ThemeMode.dark : ThemeMode.light;
    notifyListeners();
  }

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

3. 调整Main.dart,确保异步初始化完成再构建UI

因为读取本地存储是异步操作,需要用FutureBuilder等待初始化完成后再渲染MaterialApp:

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

void main() async {
  // 必须调用此方法,确保在main函数中执行异步操作前绑定Flutter框架
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: SharedPreferences.getInstance(),
      builder: (context, snapshot) {
        // 本地存储未初始化完成时,显示加载过渡界面
        if (!snapshot.hasData) {
          return const MaterialApp(
            home: Scaffold(
              body: Center(child: CircularProgressIndicator()),
            ),
          );
        }
        return MultiProvider(
          providers: [
            ChangeNotifierProvider(create: (context) => ThemeProvider()),
          ],
          child: Builder(builder: (BuildContext context) {
            final themeProvider = Provider.of<ThemeProvider>(context);
            return MaterialApp(
              debugShowCheckedModeBanner: false,
              title: 'Unit Converter',
              home: const HomePage(),
              themeMode: themeProvider.themeMode,
              theme: MyThemes.lightTheme,
              darkTheme: MyThemes.darkTheme,
            );
          }),
        );
      },
    );
  }
}

4. Setting_page.dart无需修改

原有的切换逻辑完全正常,toggleTheme变为异步方法不影响SwitchListTile的调用(onChanged不需要等待异步完成,notifyListeners会自动更新UI状态)。

内容的提问来源于stack exchange,提问作者Abu Bakar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:54:55