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

Flutter平台亮度异常:状态栏图标不随应用主题切换

解决Flutter主题切换时状态栏图标颜色不匹配问题

问题概述

应用提供「跟随系统」「浅色」「深色」三种主题切换选项,但状态栏图标颜色始终为白色,导致浅色主题下图标不可见。尝试以下代码设置状态栏样式无效:

// Determine the app brightness (theme)
final brightness = PlatformDispatcher.instance.platformBrightness;

print("Brightness: $brightness");

SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
  statusBarIconBrightness: brightness == Brightness.dark
      ? Brightness.light
      : Brightness.dark, // status bar color
));

日志显示:无论应用选择哪种主题,PlatformDispatcher.instance.platformBrightness始终返回系统UI的亮度(系统设为浅色则返回Brightness.light,设为深色则返回Brightness.dark)。

原因说明

PlatformDispatcher.instance.platformBrightness的设计就是返回系统级别的UI亮度,和应用自身的themeMode无关,这是该API的正常行为,并非实现错误。

正确解决方案

要根据应用当前实际使用的主题设置状态栏图标颜色,需结合themeMode和系统亮度计算应用实际亮度,或通过上下文获取当前主题的亮度。

方案1:基于themeMode计算应用实际亮度

在MesMaterialApp的build方法中,通过themeMode推导应用当前的亮度:

@override
Widget build(BuildContext context, WidgetRef ref) {
  final themeMode = ref.watch(settingsProvider.select((s) => s.theme));
  final systemBrightness = PlatformDispatcher.instance.platformBrightness;
  
  // 计算应用实际使用的亮度
  final appBrightness = switch(themeMode) {
    ThemeMode.light => Brightness.light,
    ThemeMode.dark => Brightness.dark,
    ThemeMode.system => systemBrightness,
  };

  // 设置状态栏样式
  SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
    statusBarIconBrightness: appBrightness == Brightness.dark 
        ? Brightness.light 
        : Brightness.dark,
    statusBarColor: appBrightness == Brightness.dark 
        ? Colors.white 
        : Colors.black,
  ));

  // ... 其余原有代码(创建主题、返回MaterialApp等)
}

方案2:通过上下文获取当前主题亮度(推荐用于子Widget)

如果是在MaterialApp的子页面或组件中,可以直接通过MediaQuery获取当前上下文的主题亮度,结果更准确:

// 在子页面的build方法中
final appBrightness = MediaQuery.of(context).platformBrightness;
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
  statusBarIconBrightness: appBrightness == Brightness.dark 
      ? Brightness.light 
      : Brightness.dark,
));

注意点

  • 不要在MaterialApp的build方法中直接使用MediaQuery.of(context),此时MaterialApp尚未完成构建,上下文不包含应用主题信息。
  • 当themeMode变化时,ConsumerWidget会自动触发build,此时重新计算并设置状态栏样式即可同步更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 21:35:05