在main.dart中使用ChangeNotifierProvider实现暗黑模式时遇非空断言错误
问题分析与修复方案
错误根源
你碰到的Failed assertion: Boolean expression must not be null错误,核心问题是**MyApp的isDark参数未被正确传入,导致其值为null**,进而在创建ThemeSettings实例时传递了null的布尔值,触发了非空断言失败。
看你的代码:
main函数里已经正确获取了isDark值(sharedPreferences.getBool("is_dark") ?? false),但创建MyApp时完全没传这个参数:runApp(MyApp())MyApp类的isDark成员没有默认值,默认就是null,当你在create: (context) => ThemeSettings(isDark)时,相当于把null传给了ThemeSettings,最终导致布尔表达式的非空断言错误。
修复步骤
给
MyApp传入isDark参数
修改main里的runApp调用:return runApp( MyApp(isDark: isDark), );可选:给
MyApp的isDark加默认值
为避免后续忘记传参再出问题,给构造函数参数加默认值:MyApp({Key key, this.isDark = false});确保
ThemeSettings正确处理布尔参数
你的ThemeSettings类需要基于传入的布尔值生成对应主题,示例如下:class ThemeSettings extends ChangeNotifier { bool _isDark; ThemeData get currentTheme => _isDark ? ThemeData.dark() : ThemeData.light(); ThemeSettings(bool isDark) : _isDark = isDark; // 可选:添加切换主题的方法 void toggleTheme() { _isDark = !_isDark; notifyListeners(); } }
修复后的完整代码
import 'package:provider/provider.dart'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); final isDark = sharedPreferences.getBool("is_dark") ?? false; return runApp( MyApp(isDark: isDark), ); } class MyApp extends StatelessWidget { final bool isDark; MyApp({Key key, this.isDark = false}); @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => ThemeSettings(isDark), builder: (context, snapshot) { final settings = Provider.of<ThemeSettings>(context); return MaterialApp( debugShowCheckedModeBanner: false, title: 'Flutter Demo', theme: settings.currentTheme, home: MyHomePage(), ); }, ); } } class ThemeSettings extends ChangeNotifier { bool _isDark; ThemeData get currentTheme => _isDark ? ThemeData.dark() : ThemeData.light(); ThemeSettings(bool isDark) : _isDark = isDark; void toggleTheme() { _isDark = !_isDark; notifyListeners(); } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("暗黑模式演示")), body: Center( child: ElevatedButton( onPressed: () { Provider.of<ThemeSettings>(context, listen: false).toggleTheme(); }, child: Text("切换主题"), ), ), ); } }
内容的提问来源于stack exchange,提问作者Hum Tum
相关产品推荐
相关产品推荐

