Flutter:如何根据明暗模式切换系统导航栏颜色?
你之前的代码没生效,核心原因是SystemChrome的设置没有随着主题变化被重新触发——大概率只在某个初始化阶段执行了一次,主题切换时没有同步更新系统导航栏样式。下面给你两个实用的解决方案:
方案一:在Consumer的builder中实时同步设置
既然已经在用Consumer监听DarkThemeProvider的状态变化,直接把SystemChrome的配置代码放到builder函数里,每次主题切换触发build时,都会重新设置系统导航栏:
@override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => themeProvider,) ], child: Consumer<DarkThemeProvider>( builder: (BuildContext context, value, Widget child){ // 每次主题变化时重新设置系统UI样式 SystemChrome.setSystemUIOverlayStyle( SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: value.darkTheme ? Brightness.light : Brightness.dark, systemNavigationBarColor: value.darkTheme ? Colors.black : Colors.white, systemNavigationBarIconBrightness: value.darkTheme ? Brightness.light : Brightness.dark ) ); return MaterialApp( theme: Style.themeData(value.darkTheme, context), home: Mainpage(), ); }, ) ); }
方案二:监听Provider状态变化(解耦UI与系统设置)
如果不想把系统UI设置和UI构建逻辑混在一起,可以在initState里给themeProvider添加监听,主题切换时自动触发导航栏更新,更优雅:
@override void initState() { getCurrentAppTheme(); // 给主题Provider添加状态监听 themeProvider.addListener(_updateSystemNavBarStyle); super.initState(); } @override void dispose() { // 记得移除监听,避免内存泄漏 themeProvider.removeListener(_updateSystemNavBarStyle); super.dispose(); } // 单独处理系统导航栏样式更新 void _updateSystemNavBarStyle() { SystemChrome.setSystemUIOverlayStyle( SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: themeProvider.darkTheme ? Brightness.light : Brightness.dark, systemNavigationBarColor: themeProvider.darkTheme ? Colors.black : Colors.white, systemNavigationBarIconBrightness: themeProvider.darkTheme ? Brightness.light : Brightness.dark ) ); }
关键注意点
- 确保你的
DarkThemeProvider在切换主题时调用了notifyListeners(),否则无论是Consumer还是监听器都不会收到状态变化通知。 - 如果你的
Style.themeData已经配置了状态栏亮度,要和SystemChrome的设置保持一致,避免显示冲突。 - 部分Android设备或系统版本对导航栏颜色有强制要求(比如必须不透明),测试时注意适配这类场景。
内容的提问来源于stack exchange,提问作者K.k
相关产品推荐
相关产品推荐

