Flutter GetX出现Controller未找到错误及Get.to路由不生效问题
问题1:"XXXController not found"报错修复
报错原因
- 你同时为
GetMaterialApp配置了home和initialRoute两个互斥参数,优先级冲突,且home对应的Scaffold在初始化时,initialBinding还未完成控制器注入,直接调用Get.find<NavigationBarController>()必然找不到实例。 - 你代码里的
Widget1、Widget2是直接作为IndexedStack的子组件初始化的,没有走GetX路由体系,所以你为两个Widget配置的Widget1_Bindings、Widget2_Bindings完全不会触发,后续你在Widget内部调用对应Controller也会报相同错误。 - 你没有用
Obx包裹响应式变量的监听位置,切换tab时UI也不会更新。
修复步骤
- 删掉
GetMaterialApp的home参数,新增HomePage作为初始路由承载Scaffold、底部导航、IndexedStack逻辑,修改后的GetMaterialApp配置如下:
return GetMaterialApp( initialBinding: HomeBinding(), initialRoute: '/', getPages: [ GetPage(name: '/', page: () => HomePage()), GetPage( name: '/widget1', page: () => Widget1(), binding: Widget1_Bindings(), ), GetPage( name: '/widget2', page: () => Widget2(), binding: Widget2_Bindings(), ), ], debugShowCheckedModeBanner: false, themeMode: ThemeMode.system, );
- 新增
HomePage组件代码:
class HomePage extends StatelessWidget { // 提前获取控制器,HomeBinding已经提前注入 final navController = Get.find<NavigationBarController>(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Demo"), ), body: SafeArea( // 用Obx监听tabIndex变化 child: Obx(() => IndexedStack( index: navController.tabIndex.value, children: const [ Widget1(), Widget2() ], )), ), bottomNavigationBar: Obx(() => BottomNavigationBar( currentIndex: navController.tabIndex.value, onTap: navController.changeTabIndex, items: [ _bottomNavigationBarItem( icon: CupertinoIcons.home, label: 'Button1', ), _bottomNavigationBarItem( icon: CupertinoIcons.rocket_fill, label: 'Button2', ), ])), ); } }
- 如果你需要在
Widget1、Widget2里使用Controller1、Controller2,有两个方案:- 方案1:在
HomeBinding里补充两个Controller的注入逻辑:
class HomeBinding extends Bindings { @override void dependencies() { Get.lazyPut(() => NavigationBarController()); Get.lazyPut(() => Controller1()); Get.lazyPut(() => Controller2()); } }- 方案2:不用IndexedStack,切换tab时调用
Get.offNamed跳转到对应路由,即可触发对应路由的Binding注入。
- 方案1:在
问题2:Get.to路由使用方法
GetX的路由跳转有两种常用写法:
- 跳转已配置在
getPages里的页面,用命名路由跳转:
// 跳转到Widget2页面,页面会压入当前路由栈,返回可回到上一页 Get.toNamed('/widget2'); // 替换当前路由页为Widget2,无返回动画 Get.offNamed('/widget2'); // 清空整个路由栈再跳转到Widget2,一般用于首页跳转 Get.offAllNamed('/widget2');
- 跳转未在
getPages里配置的临时页面,直接传组件实例:
Get.to(() => NewCustomPage());
注意:如果你是底部tab切换场景,不要用Get.to跳转,否则新页面会压入栈,底部导航栏会被覆盖,用你原来的IndexedStack方案修改后即可正常切换
内容的提问来源于stack exchange,提问作者Dmitry Bubnenkov
相关产品推荐
相关产品推荐

