decide the route based on the initialization phase of flutter_native_splash

Viewed 131

I'm writing a flutter application using flutter 2.10 and I'm debugging it using an Android Emulator

I included the flutter_native_splash plugin from https://pub.dev/packages/flutter_native_splash and I use version 2.0.1+1

the problem that I'm having is that I decide what's the first screen that the user will see based on the initialization phase. I check the stored user token, see his premissions, verify them with the server, and forward him to him relevant route.

since the runApp() function executes in the background while the initialization phase is running I cannot choose the page that will be shown. and if I try to nativgate to a route in the initialization function I get an exception.

as a workaround for now I created an init_home route with FutureBuilder that awaits for a global variable called GeneralService.defaultRoute to be set and then changes the route.

class _InitHomeState extends State<InitHome> {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<dynamic>(
        future: () async {
          var waitCount=0;
          while (GeneralService.defaultRoute  == "") {
            waitCount++;
            await Future.delayed(const Duration(milliseconds: 100));
            if (waitCount>20) {
              break;
            }
          }
          if (GeneralService.defaultRoute == "") {
            return Future.error("initialization failed");
          }
          Navigator.of(context).pushReplacementNamed(GeneralService.defaultRoute);
          ...

any ideas how to resolve this issue properly ?

1 Answers

I use a Stateful widget as Splash Screen. In the build method, you just return the 'loading' view such as Container with a background color etc. (with texts or whatever you like but just consider it as the loading screen).

In the initState(), you call a function that we can name redirect(). This should be an async function that performs the queries/checks and at the end, calls the Navigator.of(context).pushReplacementNamed etc.

class _SplashState extends State<Splash> {
  @override
  void initState() {
    super.initState();
    redirect();
  }

  @override
  Widget build(BuildContext context) {
     return Container(color: Colors.blue);
  }

  Future<void> redirect() async {
    var name = 'LOGIN';
    ... // make db calls, checks etc
    Navigator.of(context).pushReplacementNamed(name);
  }
}

Your build function just creates the loading UI, and the redirect function in the initState is the one running in the background and when it has finished computing, calls the Navigator.push to your desired page.

Related