Flutter设置自定义浅色主题时出现Unexpected null value错误
问题原因
报错的核心原因是在MaterialApp初始化时,传入的context还未绑定Material主题:
- 你在
CustomTheme.lightTheme(BuildContext context)方法中第一行调用了Theme.of(context),试图从传入的context获取上层主题 - 但这个context是
MyApp的build方法传递的,此时MaterialApp还没完成挂载,当前位置的context不存在关联的Theme对象,空安全模式下触发空值检查失败,抛出Unexpected null value错误 - 你写的深色主题能正常运行,是因为
darkTheme方法内部没有调用Theme.of(context)获取不存在的上层主题,所以不会触发空值异常。
修复方案
不需要依赖外层未初始化的context获取主题,直接基于Flutter提供的默认基础主题构造自定义主题即可,修改步骤如下:
- 调整
lightTheme方法,移除对外部context的依赖,改用默认亮主题作为基础:
// 去掉方法的context入参 static ThemeData lightTheme() { // 直接使用默认亮主题作为基础,不需要从外部context获取 final baseTheme = ThemeData(brightness: Brightness.light); return ThemeData( brightness: Brightness.light, primarySwatch: MaterialColor( Palette.color500.value, const { 100: Palette.color100, 200: Palette.color200, 300: Palette.color300, 400: Palette.color400, 500: Palette.color500, 600: Palette.color600, 700: Palette.color700, 800: Palette.color800, 900: Palette.color900, }, ), // 注:旧版本的accentColor已废弃,推荐使用colorScheme配置强调色 colorScheme: ColorScheme.fromSwatch( primarySwatch: MaterialColor( Palette.color500.value, const { 100: Palette.color100, 200: Palette.color200, 300: Palette.color300, 400: Palette.color400, 500: Palette.color500, 600: Palette.color600, 700: Palette.color700, 800: Palette.color800, 900: Palette.color900, }, ), brightness: Brightness.light, ).copyWith(secondary: Palette.color500), scaffoldBackgroundColor: Palette.almostBlack, appBarTheme: const AppBarTheme( elevation: 0, // 旧版本AppBarTheme的color字段也推荐改用backgroundColor backgroundColor: Palette.almostBlack, ), sliderTheme: SliderThemeData( activeTrackColor: Colors.white, inactiveTrackColor: Colors.grey.shade800, thumbColor: Colors.white, valueIndicatorColor: Palette.color500, inactiveTickMarkColor: Colors.transparent, activeTickMarkColor: Colors.transparent, ), textTheme: baseTheme.primaryTextTheme .copyWith( button: baseTheme.primaryTextTheme.button?.copyWith( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ) .apply( displayColor: Colors.white, ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( backgroundColor: Palette.color500, ), ), ); }
- 修改
main.dart中调用主题的代码,去掉context传参:
return MaterialApp( title: 'My App', // 不需要传context theme: CustomTheme.lightTheme(), // 深色主题也建议同步改成无context依赖的写法 darkTheme: CustomTheme.darkTheme(), home: Scaffold( // 其余原有代码保持不变 ), );
补充:如果确实需要依赖context获取局部主题配置,可以把主题构造逻辑放到MaterialApp的
builder回调或者页面子组件中,不要在MaterialApp初始化传参阶段使用外层context获取主题。
内容的提问来源于stack exchange,提问作者gegobyte
相关产品推荐
相关产品推荐

