Search code examples
flutterdartsplash-screenflutter-getx

Getx onInit not calling


Any reason why app keep stuck on splash screen? I using getx state management. If authToken not empty, it should go to main page. But onInit in controller class not calling.

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(),
    );
  }
}

Splash Screen

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();
  }
}

Bind

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!));
  }
}

Edit

I tried use middlewares, but I got error

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 [
              ....
      ],
    );
  }
}

Middleware

  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");
      }
    }

Error

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

Solution

  • You need to initialize your bindings somewhere before using/finding them. A good place is to provide an instance of your binding class (in your case Bind) to the initialBinding property of GetMaterialApp:

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

    Then you can use the Middleware approach. But the controller approach may not work just yet because the controller instance isn't used on the page/view. Remember a controller (or any other dependency) will get initialized (thus calling the lifecycle methods like onInit) only when the controller/dependency is used/called from the page/view. Which isn't happening in your case.