• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

“Controller“ not found. You need to call “Get.put(Controller())“ or “Get..lazyPut(()=>Controller()

武飞扬头像
Chen_ShengJie
帮助1

项目中使用 GetX,使用 GetX 依赖注入。创建 ShowToastBinding 类,并绑定ShowToastController。

  1.  
    class ShowToastBinding implements Bindings {
  2.  
     
  3.  
      @override
  4.  
      void dependencies() {
  5.  
     
  6.  
        Get.lazyPut<ShowToastController>(
  7.  
     
  8.  
              () => ShowToastController(
  9.  
     
  10.  
          ),
  11.  
     
  12.  
        );
  13.  
     
  14.  
      }
  15.  
     
  16.  
    }

在GetPage我添加了这个绑定,比如:

  1.  
    class Routes{
  2.  
     
  3.  
      static const String SHOWTOAST="/ShowToast";
  4.  
     
  5.  
      static final pages = [
  6.  
     
  7.  
        GetPage(
  8.  
     
  9.  
          name: Routes.SHOWTOAST,
  10.  
     
  11.  
          page: () => ShowToastWidget(),
  12.  
     
  13.  
          binding: ShowToastBinding(),
  14.  
     
  15.  
        )
  16.  
     
  17.  
      ];
  18.  
     
  19.  
    }

新建ShowToastController类继承GetxController,并添加一个普通函数showToastView()

  1.  
    class ShowToastController extends GetxController 
  2.  
     
  3.  
      void showToastView() {
  4.  
     
  5.  
      }
  6.  
     
  7.  
    }

新建HomeController,对TabController进行初始化操作,也贴下代码:

  1.  
    class HomeController extends GetxController with GetSingleTickerProviderStateMixin  {
  2.  
     
  3.  
     
  4.  
      TabController? tabController;
  5.  
     
  6.  
      @override
  7.  
     
  8.  
      void onInit() {
  9.  
     
  10.  
        super.onInit();
  11.  
     
  12.  
        ///添加监听器
  13.  
     
  14.  
        tabController =
  15.  
     
  16.  
            TabController(initialIndex: 0, vsync: this, length:2);
  17.  
     
  18.  
      }
  19.  
     
  20.  
    }

现在主界面如下:

  1.  
    class TabPage extends GetView<HomeController> {
  2.  
     
  3.  
      @override
  4.  
     
  5.  
      Widget build(BuildContext context) {
  6.  
     
  7.  
        return Scaffold(
  8.  
     
  9.  
          appBar: AppBar(
  10.  
     
  11.  
            title: TabBar(
  12.  
     
  13.  
              controller: controller.tabController,
  14.  
     
  15.  
              tabs: [
  16.  
     
  17.  
                Tab( child: Text("one",),),
  18.  
     
  19.  
                Tab( child: Text("two",),
  20.  
     
  21.  
                ),
  22.  
     
  23.  
              ],
  24.  
     
  25.  
            ),
  26.  
     
  27.  
          ),
  28.  
     
  29.  
          body: Padding(
  30.  
     
  31.  
            padding: const EdgeInsets.all(8.0),
  32.  
     
  33.  
            child: TabBarView(
  34.  
     
  35.  
              controller: controller.tabController,
  36.  
     
  37.  
              physics: const NeverScrollableScrollPhysics(),
  38.  
     
  39.  
              children: [
  40.  
     
  41.  
                Center(
  42.  
     
  43.  
                  child: Container(
  44.  
     
  45.  
                    width: 200,
  46.  
     
  47.  
                    height: 50,
  48.  
     
  49.  
                    color: Colors.red,
  50.  
                  ),
  51.  
     
  52.  
                ),
  53.  
     
  54.  
                ShowToastWidget(),
  55.  
              ],
  56.  
     
  57.  
            ),
  58.  
     
  59.  
          ),
  60.  
     
  61.  
        );
  62.  
     
  63.  
      }
  64.  
     
  65.  
    }

添加2个tab按钮 名字分别为one 和two  one对应的界面是一个居中的红色背景的Container,two对应的是我们新增的布局 ShowToastWidget.同样TabPage 和ShowToastWidget去添加GetX依赖注入,如下

  1.  
     static const String tab_page="/tabpage";
  2.  
     
  3.  
      static final pages = [
  4.  
     
  5.  
        GetPage(
  6.  
            name: Routes.tab_page,
  7.  
            page: () => TabPage(),
  8.  
            binding:TabPageBinding()),
  9.  
     
  10.  
      ];

再来看下ShowToastWidget界面:

  1.  
    class ShowToastWidget extends GetView<ShowToastController> {
  2.  
     
  3.  
      @override
  4.  
      Widget build(BuildContext context) {
  5.  
     
  6.  
        return Scaffold(
  7.  
          body: Center(
  8.  
     
  9.  
              child: Container(
  10.  
     
  11.  
            width: 200,
  12.  
     
  13.  
            height: 50,
  14.  
     
  15.  
            child: ElevatedButton(
  16.  
     
  17.  
              onPressed: () {
  18.  
     
  19.  
                controller.showToastView();
  20.  
     
  21.  
              },
  22.  
     
  23.  
              child: Text("showToast"),
  24.  
     
  25.  
            ),
  26.  
     
  27.  
          )),
  28.  
     
  29.  
        );
  30.  
     
  31.  
      }
  32.  
     
  33.  
    }

继承getX框架中的GetView布局,并引入ShowToastController 这样就可以在当前布局调用ShowToastController里面的函数了。显示一个居中按钮 点击调用ShowToastController里的showToastView方法。

最后看下程序入口mian.dart

  1.  
    Future<void> main() async {
  2.  
      runApp( HomeWidget());
  3.  
    }
  4.  
     
  5.  
    class HomeWidget extends StatefulWidget {
  6.  
     
  7.  
      @override
  8.  
     
  9.  
      _HomeWidgetState createState() => _HomeWidgetState();
  10.  
     
  11.  
    }
  12.  
     
  13.  
    class _HomeWidgetState extends State<HomeWidget> {
  14.  
     
  15.  
      @override
  16.  
     
  17.  
      Widget build(BuildContext context) {
  18.  
     
  19.  
        return GetMaterialApp(
  20.  
     
  21.  
          getPages: Routes.pages,
  22.  
     
  23.  
          initialBinding: TabPageBinding(),
  24.  
     
  25.  
          home: Scaffold(
  26.  
     
  27.  
            body: Center(
  28.  
     
  29.  
              child: Container(
  30.  
     
  31.  
                child: ElevatedButton(
  32.  
     
  33.  
                  onPressed: () {
  34.  
     
  35.  
                    Get.toNamed(Routes.tab_page);
  36.  
     
  37.  
                  },
  38.  
     
  39.  
                  child: Text("点击"),
  40.  
     
  41.  
                ),
  42.  
     
  43.  
              ),
  44.  
     
  45.  
            ),
  46.  
     
  47.  
          ),
  48.  
     
  49.  
        );
  50.  
     
  51.  
      }
  52.  
     
  53.  
    }

使用GetX需要把MaterialApp改成GetMaterialApp才能使用,getPages去获取我们路由跳转的界面,initialBinding 我们就用TabPageBinding吧。

ok,现在整个界面应该是这样的:

程序运行 进入首界面,中间显示一个 ”点击“的按钮,然后点击按钮跳转到 有2个tab的TabView界面, 名为one的tab 界面下显示一个红色长方形的布局,点击名为two的tab 对应下面显示一个 名为”showToast"的居中按钮。

问题复现的步骤:

1、点击第一个界面的点击按钮

2、然后点击名为 two的tab标签

3、点击 showToast的按钮

4、查看日志

日志信息如下:

The following message was thrown while handling a gesture:

"ShowToastController" not found. You need to call "Get.put(ShowToastController())" or "Get.lazyPut(()=>ShowToastController())"

When the exception was thrown, this was the stack:

#0      GetInstance.find (package:get/get_instance/src/get_instance.dart:305:7)

#1      GetView.controller (package:get/get_state_manager/src/simple/get_view.dart:38:37)

#2      ShowToastWidget.build.<anonymous closure> (package:flutter_test_demo/get/AddPage.dart:21:13)

#3      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:989:21)

#4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)

...

显而易见,日志显示是GetX的Controller找不到。但我们确实依赖注入了呀。

  1.  
     GetPage(
  2.  
     
  3.  
          name: Routes.SHOWTOAST,
  4.  
     
  5.  
          page: () => ShowToastWidget(),
  6.  
     
  7.  
          binding: ShowToastBinding(),
  8.  
     
  9.  
        )

 这时候我们突然也想到了 TabPage的注入方式和我们的ShowToastWidget 一毛一样的,为啥进入TabPage的时候,没有报这个错误?

细心的你们肯定发现了区别。TabPage 是在HomeWidget界面通过Get.toNamed(Routes.tab_page)跳转进入的,而 ShowToastWidget界面是通过tab点击进入的。

所以问题就是:跳转到ShowToastWidget界面没有使用 GetX 导航系统。是从同一页面切换选项卡。因此,ShowToastBinding该类对其没有影响。

Get.toNamed(Routes.SHOWTOAST)仅当您使用或导航时它才会生效Get.to(()=>ShowToastWidget(), binding: ShowToastBinding()),或者使用 Get.toNamed(Routes.SHOWTOAST)且 GetPage(

      name: Routes.SHOWTOAST,

      page: () => ShowToastWidget(),

      binding: ShowToastBinding(),

    );  

除了tab 切换会导致这个问题,只要我们未使用GetX的路由跳转都会出现这个问题,比如我们在one tab界面下新增个按钮,用原生的代码去实现界面的跳转也会出现同样的问题:

  1.  
    TabBarView(
  2.  
     
  3.  
              controller: controller.tabController,
  4.  
     
  5.  
              physics: const NeverScrollableScrollPhysics(),
  6.  
     
  7.  
              children: [
  8.  
     
  9.  
                Center(
  10.  
     
  11.  
                  child: Container(
  12.  
     
  13.  
                    width: 200,
  14.  
     
  15.  
                    height: 50,
  16.  
     
  17.  
                    child: ElevatedButton(onPressed: (){
  18.  
     
  19.  
                      Navigator.push(context,
  20.  
     
  21.  
                          MaterialPageRoute(builder: (context) => ShowToastWidget()));
  22.  
     
  23.  
                    },child: Text("跳转"),),
  24.  
     
  25.  
                  ),
  26.  
     
  27.  
                ),
  28.  
     
  29.  
                ShowToastWidget(),
  30.  
     
  31.  
              ],
  32.  
     
  33.  
            )

解决问题的方案:

  第一种就是采用 GetX的界面路由跳转方案。Get.to(()=>ShowToastWidget(), binding: ShowToastBinding())或使用 Get.toNamed(Routes.SHOWTOAST)且 GetPage(

      name: Routes.SHOWTOAST,

      page: () => ShowToastWidget(),

      binding: ShowToastBinding(),

    );  

  第二种就是像tab标签切换这种,把ShowToastBinding的依赖添加到TabPageBinding里,看如下操作:

  1.  
     GetPage(
  2.  
     
  3.  
            name: Routes.tab_page,
  4.  
     
  5.  
            page: () => TabPage(),
  6.  
     
  7.  
            bindings:[ TabPageBinding(),ShowToastBinding()]),

     在添加TabPage的getX依赖注入时,bindings里添加ShowToastBinding的绑定。这样修改后,继续走下上面问题复现的步骤,会发现问题不再复现了。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfkjgba
系列文章
更多 icon
同类精品
更多 icon
继续加载