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
相关产品推荐
相关产品推荐

