Flutter中如何根据屏幕内容(弹窗/夜间模式)动态更改导航栏颜色?
解决Flutter导航栏动态适配弹窗与夜间模式的方案
针对你遇到的导航栏在弹窗、夜间模式下的适配问题,可以通过动态切换SystemUI样式的方式替代临时方案,实现更流畅的适配效果。
1. 封装通用导航栏样式更新方法
先封装一个方法,根据当前背景色调自动调整导航栏的图标亮度和背景色:
import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; void updateSystemUIOverlayStyle(bool isDarkBackground) { SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( statusBarColor: Colors.transparent, // 状态栏图标亮度:深色背景用浅色图标,浅色背景用深色图标 statusBarIconBrightness: isDarkBackground ? Brightness.light : Brightness.dark, // 导航栏背景色:深色背景下设为黑色,浅色背景保持透明 systemNavigationBarColor: isDarkBackground ? Colors.black : Colors.transparent, // 导航栏图标亮度:和状态栏逻辑一致 systemNavigationBarIconBrightness: isDarkBackground ? Brightness.light : Brightness.dark, systemNavigationBarDividerColor: Colors.transparent, )); }
2. 弹窗场景适配
在弹窗显示前切换为深色背景适配的样式,弹窗关闭后恢复原样式:
// 显示弹窗的逻辑 void showCustomDialog(BuildContext context) { // 弹窗显示前,切换为适配暗化背景的导航栏样式 updateSystemUIOverlayStyle(true); showDialog( context: context, barrierColor: Colors.black54, // 暗化背景 builder: (context) => AlertDialog( title: const Text('提示'), content: const Text('这是一个暗化背景的弹窗'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('确定'), ), ], ), ).then((_) { // 弹窗关闭后,恢复适配浅色主体的导航栏样式 updateSystemUIOverlayStyle(false); }); }
3. 夜间模式适配
基于系统ThemeMode的适配
如果使用Flutter默认的ThemeMode管理夜间模式,可以在页面的didChangeDependencies方法中监听主题变化,自动更新导航栏:
class ReaderPage extends StatefulWidget { const ReaderPage({super.key}); @override State<ReaderPage> createState() => _ReaderPageState(); } class _ReaderPageState extends State<ReaderPage> { @override void didChangeDependencies() { super.didChangeDependencies(); // 判断当前主题是否为深色模式 final isDarkMode = Theme.of(context).brightness == Brightness.dark; updateSystemUIOverlayStyle(isDarkMode); } @override Widget build(BuildContext context) { return Scaffold( // 阅读器页面内容 body: const Center(child: Text('阅读器页面')), ); } }
自定义夜间模式状态的适配
如果使用自定义状态管理(如Provider)控制夜间模式,可以在状态切换时直接调用更新方法:
// 自定义主题状态管理类 class ThemeProvider with ChangeNotifier { bool _isDarkMode = false; bool get isDarkMode => _isDarkMode; void toggleDarkMode() { _isDarkMode = !_isDarkMode; notifyListeners(); // 切换模式时同步更新导航栏样式 updateSystemUIOverlayStyle(_isDarkMode); } } // 在页面中使用Provider切换夜间模式 ElevatedButton( onPressed: () { Provider.of<ThemeProvider>(context, listen: false).toggleDarkMode(); }, child: const Text('切换夜间模式'), )
初始化保留原设置
在main函数中仍保留你原来的初始化代码,确保应用启动时的默认样式正确:
void main() { WidgetsFlutterBinding.ensureInitialized(); SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge, overlays: [SystemUiOverlay.bottom]); // 初始样式适配浅色主体 updateSystemUIOverlayStyle(false); runApp(const MyApp()); }
内容的提问来源于stack exchange,提问作者Patryk
相关产品推荐
相关产品推荐

