Flutter+Getx导航时出现Widget Tree重复GlobalKey问题
问题分析与解决
错误原因
你遇到的Duplicate GlobalKey detected in widget tree错误,核心原因有两个:
- 静态GlobalKey重复使用:
PageOneBuilder里的formKey被定义为static,这意味着整个应用中只有这一个GlobalKey实例。当你用Get.to(() => const PageOne())从Page3跳转到新的Page1时,原来的Page1还保留在导航栈中,两个PageOne里的Form组件会共用同一个静态formKey,触发重复Key的错误。 - 导航方式导致重复页面:使用
Get.to跳转Page1会把新的Page1实例压入导航栈,栈中同时存在多个Page1,进一步加剧了GlobalKey的冲突问题。
具体修复步骤
1. 移除GlobalKey的static修饰
把PageOneBuilder中的静态formKey改为实例变量,让每个PageOne实例拥有独立的GlobalKey:
class PageOneBuilder { PageOneBuilder(this.context); BuildContext context; final controller = Get.put(PageOneController()); // 去掉static,改为实例变量 final GlobalKey<FormState> formKey = GlobalKey<FormState>(); //------------------- other codes here --------------- }
2. 优化控制器的注册方式(可选但推荐)
每次创建PageOneBuilder时调用Get.put(PageOneController())会导致重复注册控制器(如果栈中已有Page1),建议改为Get.find或者提前懒加载控制器来避免:
// 在PageOneBuilder中改为: final controller = Get.find<PageOneController>(); // 然后在应用初始化阶段注册控制器(比如main.dart中): Get.lazyPut(() => PageOneController());
3. 修改Page3到Page1的导航方式
不要用Get.to压入新的Page1,而是用Get.offAll清空导航栈并跳转到新的Page1,这样栈中只会保留一个Page1实例,从根源避免重复:
// Page3的跳转代码改为: Get.offAll(() => const PageOne());
如果你的需求是回到最初的那个Page1而不是创建新实例,可以给PageOne配置路由名称后用Get.until返回:
// 先在GetMaterialApp的routes中配置PageOne的路由名 Get.until((route) => route.settings.name == '/page1');
内容的提问来源于stack exchange,提问作者WatsMyName
相关产品推荐
相关产品推荐

