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

Flutter主题管理:启动主题闪烁及LateInitializationError问题求助

用Riverpod实现主题切换的启动闪屏与初始化问题解决

问题场景

使用Riverpod实现主题切换并通过SharedPreferences保存ThemeMode,功能整体正常,但存在以下问题:

  • 当设置late ThemeMode _themeMode = ThemeMode.system;时,应用启动会短暂显示默认主题,出现视觉闪屏;
  • 若仅声明late ThemeMode _themeMode;不设置初始值,会触发LateInitializationError: field '_themeMode@47036434' has not been initialised错误,虽应用不崩溃但存在异常;
  • 尝试去掉late改为可空类型,问题仍未解决。

原实现代码

main.dart

void main() async {
  WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
  FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
  await SharedPreferences.getInstance();

  runApp(const ProviderScope(child: MyApp()));
}


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

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Demo App',
      theme: myLightTheme,
      darkTheme: myDarkTheme,
      themeMode: ref.watch(themeModeProvider).mode,
      home: const HomeScreen(),
    );
  }
}

ThemeModeNotifier

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

import '../utils/theme_mode.dart';

final themeModeProvider = ChangeNotifierProvider((ref) => ThemeModeNotifier());

class ThemeModeNotifier extends ChangeNotifier {

  late ThemeMode _themeMode = ThemeMode.system;

  ThemeModeNotifier() {
    _init();
  }

  ThemeMode get mode => _themeMode;

  void _init() async {
    _themeMode = await loadThemeMode(); // 从SharedPreferences获取ThemeMode
    notifyListeners();
  }

  void update(ThemeMode nextMode) async {
    _themeMode = nextMode;
    await saveThemeMode(nextMode); // 将ThemeMode保存到SharedPreferences
    notifyListeners();
  }
}

theme_mode工具类

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

int modeToVal(ThemeMode mode) {
  switch (mode) {
    case ThemeMode.system:
      return 1;
    case ThemeMode.dark:
      return 2;
    case ThemeMode.light:
      return 3;
    default:
      return 0;
  }
}

ThemeMode valToMode(int val) {
  switch (val) {
    case 1:
      return ThemeMode.system;
    case 2:
      return ThemeMode.dark;
    case 3:
      return ThemeMode.light;
    default:
      return ThemeMode.system;
  }
}

Future<void> saveThemeMode(ThemeMode mode) async {
  final pref = await SharedPreferences.getInstance();
  pref.setInt('theme_mode', modeToVal(mode));
  print('saveThemeMode: $mode');
}

Future<ThemeMode> loadThemeMode() async {
  final pref = await SharedPreferences.getInstance();
  final ret = valToMode(pref.getInt('theme_mode') ?? 0);
  print('loadThemeMode: $ret');
  return ret;
}

解决后的实现

通过调整存储服务的实现方式,现在主题切换正常,启动时无短暂默认主题显示:

import 'package:app_name/utils/theme_mode.dart' as theme_mode; // 新增导入

class StorageServiceImpl extends StorageService {
  @override
  Future<ThemeMode> loadThemeMode() => Future(() => theme_mode.loadThemeMode()); // 更新实现

  @override
  Future<void> saveThemeMode(ThemeMode mode) async {
    await theme_mode.saveThemeMode(mode); // 调用工具类方法
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:10:07