trigger rebuild using MaterialApp builder?

242 views Asked by At

I have a MaterialApp with a home or initialRoute (tried it both ways) as well as a builder:

MaterialApp(
  key: appKey,
  debugShowCheckedModeBanner: false,
  theme: CustomTheme.lightTheme,
  darkTheme: CustomTheme.lightTheme,
  navigatorKey: navigatorKey,
  navigatorObservers: <NavigatorObserver>[components.routes],
  //initialRoute: '/splash',
  home: Splash(),
  routes: pages.routes,
  builder: (BuildContext context, Widget? child) {
    if (flag) {
      return child!; // splash screen
    }

    print('this never prints'); // root of problem: unable to rebuild this.

    return MultiBlocProvider( // rest of the app
      providers: providers,
      child: HomePage(child: child),
    );
  }
);

So see how in the builder it has a flag - on the first run it returns the splash screen.

class Splash extends StatefulWidget {
  const Splash({Key? key}) : super(key: key ?? defaultKey);
  static const defaultKey = ValueKey('Splash');

  @override
  _SplashState createState() => _SplashState();
}

class _SplashState extends State<Splash> with TickerProviderStateMixin {
  /* animation args etc. */

  @override
  void initState() {
    super.initState();

    /* open database and stuff during splash screen animation */

    streams.app.splash.add(false); // the actual flag

    // PROBLEM: attempt to navigate to home page, doesn't work well:
    Navigator.of(navigatorKey.currentContext!)
        .pushReplacementNamed('/home');
  }

  @override
  Widget build(BuildContext context) => /* ... animated splash screen ... */;
}

See when the splash is finished I turn the flag from true to false. Unfortunately that seems to have no effect because I then use the navigatorKey to attempt to go to a new route, but it doesn't work right.

It seems to be using the splashscreen context or something, so it never reloads or never triggers a rebuild of the builder function on the MaterialApp. So it never gets into the "false" condition where I have the cubit providers and a bunch of other stuff.

Do you know how I should solve this? maybe I shouldn't even use the builder function?

1

There are 1 answers

0
Sushan Shakya On BEST ANSWER

I believe all that you want to do is the following flow :

  1. The App shows a Splash Screen.
  2. After a few seconds it shows the rest of the app.

The easiest way to achieve this is :

MaterialApp(
  ...
  home: MultiBlocProvider(
      providers: providers,
      child: Splash(),
  ),
  ...
);
class Splash extends StatefulWidget {...}

class _SplashState extends State<Splash> with TickerProviderStateMixin {
  ...

  @override
  void initState() {
    super.initState();
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(builder: (c) => HomePage())
    );
  }

  @override
  Widget build(BuildContext context) => /* ... animated splash screen ... */;
}