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

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

class ShowToastBinding implements Bindings {

  @override
  void dependencies() {

    Get.lazyPut(

          () => ShowToastController(

      ),

    );

  }

}

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

class Routes{

  static const String SHOWTOAST="/ShowToast";

  static final pages = [

    GetPage(

      name: Routes.SHOWTOAST,

      page: () => ShowToastWidget(),

      binding: ShowToastBinding(),

    )

  ];

}

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

class ShowToastController extends GetxController 

  void showToastView() {

  }

}

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

class HomeController extends GetxController with GetSingleTickerProviderStateMixin  {


  TabController? tabController;

  @override

  void onInit() {

    super.onInit();

    ///添加监听器

    tabController =

        TabController(initialIndex: 0, vsync: this, length:2);

  }

}

现在主界面如下:

class TabPage extends GetView {

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: TabBar(

          controller: controller.tabController,

          tabs: [

            Tab( child: Text("one",),),

            Tab( child: Text("two",),

            ),

          ],

        ),

      ),

      body: Padding(

        padding: const EdgeInsets.all(8.0),

        child: TabBarView(

          controller: controller.tabController,

          physics: const NeverScrollableScrollPhysics(),

          children: [

            Center(

              child: Container(

                width: 200,

                height: 50,

                color: Colors.red,
              ),

            ),

            ShowToastWidget(),
          ],

        ),

      ),

    );

  }

}

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

 static const String tab_page="/tabpage";

  static final pages = [

    GetPage(
        name: Routes.tab_page,
        page: () => TabPage(),
        binding:TabPageBinding()),

  ];

再来看下ShowToastWidget界面:

class ShowToastWidget extends GetView {

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      body: Center(

          child: Container(

        width: 200,

        height: 50,

        child: ElevatedButton(

          onPressed: () {

            controller.showToastView();

          },

          child: Text("showToast"),

        ),

      )),

    );

  }

}

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

最后看下程序入口mian.dart

Future main() async {
  runApp( HomeWidget());
}

class HomeWidget extends StatefulWidget {

  @override

  _HomeWidgetState createState() => _HomeWidgetState();

}

class _HomeWidgetState extends State {

  @override

  Widget build(BuildContext context) {

    return GetMaterialApp(

      getPages: Routes.pages,

      initialBinding: TabPageBinding(),

      home: Scaffold(

        body: Center(

          child: Container(

            child: ElevatedButton(

              onPressed: () {

                Get.toNamed(Routes.tab_page);

              },

              child: Text("点击"),

            ),

          ),

        ),

      ),

    );

  }

}

使用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. (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找不到。但我们确实依赖注入了呀。

 GetPage(

      name: Routes.SHOWTOAST,

      page: () => ShowToastWidget(),

      binding: ShowToastBinding(),

    )

 这时候我们突然也想到了 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界面下新增个按钮,用原生的代码去实现界面的跳转也会出现同样的问题:

TabBarView(

          controller: controller.tabController,

          physics: const NeverScrollableScrollPhysics(),

          children: [

            Center(

              child: Container(

                width: 200,

                height: 50,

                child: ElevatedButton(onPressed: (){

                  Navigator.push(context,

                      MaterialPageRoute(builder: (context) => ShowToastWidget()));

                },child: Text("跳转"),),

              ),

            ),

            ShowToastWidget(),

          ],

        )

解决问题的方案:

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

      name: Routes.SHOWTOAST,

      page: () => ShowToastWidget(),

      binding: ShowToastBinding(),

    );  

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

 GetPage(

        name: Routes.tab_page,

        page: () => TabPage(),

        bindings:[ TabPageBinding(),ShowToastBinding()]),

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

你可能感兴趣的:(flutter,flutter,android,开发语言)