【问题标题】:Getx onInit not callingGetx onInit 没有调用
【发布时间】:2021-12-16 16:58:01
【问题描述】:

应用卡在闪屏上有什么原因吗?我使用 getx 状态管理。如果 authToken 不为空,它应该转到主页。但是控制器类中的onInit 没有调用。

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      initialRoute: '/splashScreen',
      getPages: [
        GetPage(name: '/splashScreen', page: () => SplashScreen(),binding: Bind()),
        GetPage(
            name: '/login', page: () => LoginPage(), binding:Bind()),
        GetPage(
            name: '/mainPage', page: () => MainPage(), binding:Bind())
      ],
      debugShowCheckedModeBanner: false,
      localizationsDelegates: const [
        LocalizationDelegate(),
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('en', ''),
        const Locale('zh', ''),
      ],
      title: 'Sample',
      theme: ThemeData(
        accentIconTheme: const IconThemeData.fallback().copyWith(
          color: Colors.white,
        ),
        primaryTextTheme: TextTheme(headline6: TextStyle(color: Colors.orange)),
        primarySwatch: white,
        primaryIconTheme: const IconThemeData.fallback().copyWith(
          color: Colors.white,
        ),
      ),
      // home: SplashScreen(),
    );
  }
}

启动画面

class SplashScreen extends GetView<MainPageController> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Container(
          height: double.infinity,
          width: double.infinity,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Column(
                children: <Widget>[
                  Container(
                      height: 250,
                      width: 250,
                      child: Image.asset('assets/xxx.png')),
                  SizedBox(
                    height: 10,
                  ),
                ],
              )
            ],
          )),
    );
  }
}

MainPageController

class MainPageController extends GetxController {
  final con = Get.find<ProductDefectsController>();
  final con1 = Get.find<ProductQualityController>();
  final con2 = Get.find<ProductController>();

  var tabIndex = 0;

  @override
  void onInit() async {
    print("call onInit");  // this line not printing
    // checkIsLogin();
    // print("ww");
    super.onInit();
  }
}

绑定

class Bind extends Bindings {
  Repository? _repository;
 
  Bind() {
    final _service = Get.put(Service());
    final _db = Get.put(Db());

    final _dao = Get.put(Dao(_db));
    _repository = Get.put(Repository(_dao, _service));
  }

  @override
  void dependencies() {
    Get.lazyPut<MainPageController>(() => MainPageController());  
    Get.lazyPut<LoginPageController>(
        () => LoginPageController(_repository!));
  }
}

编辑

我尝试使用middlewares,但出现错误

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      initialRoute: '/splashScreen',
      getPages: [
        GetPage(
            name: '/splashScreen',
            page: () => SplashScreen(),
            binding: Bind(), middlewares: [GlobalMiddleware()]),
                ...
      ],
      debugShowCheckedModeBanner: false,
      localizationsDelegates: const [
              ....
      ],
    );
  }
}

中间件

  class GlobalMiddleware extends GetMiddleware {
      final authService = Get.find<LoginPageController>();
    
      @override
      RouteSettings? redirect(String? route) {
        print(authService.isLogin.value);
        return authService.isLogin.value == true
            ? RouteSettings(
                name: "/mainPage",
              )
            : RouteSettings(name: "/login");
      }
    }

错误

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

【问题讨论】:

    标签: flutter dart splash-screen flutter-getx


    【解决方案1】:

    你需要像下面的例子那样实例化你的控制器

    class HomeBindings implements Bindings {
          @override
          void dependencies() {
            Get.put(HomeController(influencerDataServices: Get.find(), cardsJobsServices: Get.find()));
            Get.lazyPut(() => AgendaCardsController(
                influencerDataServices: Get.find(), cardsJobsServices: Get.find()));
          }
        }
    

    然后在你的路由中你需要调用这个绑定,像这样:

     List<GetPage> routers = [
            GetPage(
              name: "/home",
              page: () => const HomePage(),
              binding: HomeBindings(),
              transition: Transition.leftToRightWithFade,
              opaque: false,
              showCupertinoParallax: true,
            )
          ];
    

    getx 与控制器和绑定紧密相连,您也可以在页面的就绪状态而不是初始化状态下尝试

    【讨论】:

      【解决方案2】:

      在使用/查找绑定之前,您需要在某处初始化绑定。一个好地方是向GetMaterialAppinitialBinding 属性提供绑定类的实例(在您的情况下为Bind):

      GetMaterialApp(
      ...
      initialBinding: Bind(),
      ...
      ) 
      

      然后您可以使用中间件方法。但是控制器方法可能还不能工作,因为页面/视图上没有使用控制器实例。 请记住,仅当从页面/视图使用/调用控制器/依赖项时,才会初始化控制器(或任何其他依赖项)(从而调用诸如 onInit 之类的生命周期方法)。在您的情况下没有发生这种情况。

      【讨论】:

      • 那么应该怎么解决呢?
      • 答案就是这样。我的意思是如何修复。照着做就行了
      【解决方案3】:

      我无法在这段代码中看到您使用的是 Get.put 还是 Get.lazyPut。请确保您在使用 Getx 控制器之前使用过其中一个。

      【讨论】:

      • 帖子已编辑..谢谢
      • 请询问更多信息或对评论提出改进建议。您的建议不是答案。
      猜你喜欢
      • 2021-10-03
      • 2022-12-02
      • 1970-01-01
      • 1970-01-01
      • 2021-11-06
      • 1970-01-01
      • 1970-01-01
      • 2018-02-14
      • 1970-01-01
      相关资源
      最近更新 更多