Flutter desktop_multi_window macOS窗口失焦后setState失效求助
macOS下desktop_multi_window子窗口焦点切换后setState失效的解决方案
问题现象
在macOS系统中使用desktop_multi_window包创建Flutter子窗口时,遇到如下异常:
- 切换焦点到桌面或其他应用后返回子窗口,调用
setState()无法触发UI重建(build方法无执行输出) GestureDetector的交互逻辑可正常运行,但UI无任何更新- 最大化子窗口后,
setState()和UI重建功能完全恢复正常
解决方案
问题根源是macOS非最大化窗口在重新获得焦点时,Flutter引擎的帧刷新机制未被正确触发。通过监听窗口焦点变化,手动强制调度帧刷新即可解决:
修改子窗口代码
在TestApp的State类中添加窗口焦点监听逻辑,并在窗口获得焦点时强制触发UI刷新:
class _TestAppState extends State<TestApp> { int test = 0; bool hide = false; late DesktopMultiWindowController _windowController; @override void initState() { super.initState(); // 获取当前子窗口的控制器实例 _windowController = DesktopMultiWindowController.fromWindowId( int.parse(window.arguments.toString()), ); // 监听窗口焦点变化事件 _windowController.setWindowFocusListener((isFocused) { if (isFocused) { // 窗口重新获得焦点时,强制调度帧刷新 WidgetsBinding.instance.scheduleFrame(); } }); } @override void dispose() { _windowController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { print('build'); return MaterialApp( home: GestureDetector( onTap: () { hide = !hide; setState(() {}); }, child: hide ? const Text('hidden') : Scaffold( body: Center( child: Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ Text(test.toString()), TextButton( onPressed: () { test++; setState(() {}); }, child: const Text('press')) ], ), ), ), ), ); } }
原理说明
通过setWindowFocusListener监听窗口焦点状态,当窗口重新获得焦点时调用WidgetsBinding.instance.scheduleFrame(),主动通知Flutter引擎触发下一帧的绘制流程,从而让setState()的状态变化能够正常同步到UI上,无需依赖窗口最大化操作。
内容的提问来源于stack exchange,提问作者Develocode 777
相关产品推荐
相关产品推荐

