Flutter:使用SystemUiMode.immersive后,收起键盘导航栏状态栏仍留存求解决
Flutter Immersive模式下键盘收起后导航栏残留问题解决方案
方案1:监听键盘收起事件主动重置UI模式
通过WidgetsBindingObserver监听窗口内边距变化,判断键盘是否完全收起,再重新设置沉浸式模式:
class _YourPageState extends State<YourPage> with WidgetsBindingObserver { @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } @override void didChangeMetrics() { super.didChangeMetrics(); final bottomInset = WidgetsBinding.instance.window.viewInsets.bottom; // 当底部内边距归0,说明键盘已收起 if (bottomInset == 0) { // 延迟300ms执行,避开系统键盘收起的动画周期,保证重置生效 Future.delayed(const Duration(milliseconds: 300), () { SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive); }); } } @override Widget build(BuildContext context) { // 页面内容 return Scaffold(...); } }
方案2:切换到immersiveSticky模式
如果业务场景允许,改用SystemUiMode.immersiveSticky模式,这种模式下导航栏/状态栏弹出后会自动延迟隐藏,无需手动点击:
// 在页面初始化时设置 @override void initState() { super.initState(); SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); }
注意:该模式下用户滑动边缘也会唤起UI,但会自动隐藏,适合对沉浸式要求不是极端严格的场景。
方案3:监听焦点变化触发UI重置
通过FocusManager监听输入框焦点状态,当焦点丢失(键盘大概率已收起)时重置沉浸式模式:
@override void initState() { super.initState(); FocusManager.instance.addListener(_onFocusChange); } @override void dispose() { FocusManager.instance.removeListener(_onFocusChange); super.dispose(); } void _onFocusChange() { // 没有焦点时触发重置 if (!FocusManager.instance.primaryFocus?.hasFocus ?? true) { Future.delayed(const Duration(milliseconds: 200), () { SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive); }); } }
方案4:优化全局点击隐藏逻辑
强化你已有的点击隐藏逻辑,让页面任何区域被点击时,都强制隐藏系统UI并收起键盘,避免遮挡:
@override Widget build(BuildContext context) { return GestureDetector( onTap: () { // 强制设置沉浸式模式 SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive); // 收起键盘,避免焦点残留导致UI异常 FocusScope.of(context).unfocus(); }, behavior: HitTestBehavior.opaque, // 确保空白区域也能响应点击 child: Scaffold( // 页面内容 ), ); }
内容的提问来源于stack exchange,提问作者binyamin alony
相关产品推荐
相关产品推荐

