Mehmet Esen
Mehmet Esen

Reputation: 6876

Conditional Navigation inside Widget Tree

I have asked before but things have changed, today I realized there is a serious problem with the solution I got before. My algorithm a bit changed.

This is the new code:

  @override
  Widget build(BuildContext context) {
    return Material(
      child: FutureBuilder(
        future: _future,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            print('BOOT VALUE IS ${snapshot.data}');
          }
          return !snapshot.hasData
              ? SplashScreen()
              : snapshot.data ? HomePage() : FirstScreen();
        },
      ),
    );
  }

With this solution, the BootScreen page functions execute every time while I navigate inside the pages I render conditionally inside FutureBuilder. So it's not best... I need to execute Navigation without any problem inside Future Builder, like this:

  @override
  Widget build(BuildContext context) {
    return Material(
      child: FutureBuilder(
        future: _future,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            print('BOOT VALUE IS ${snapshot.data}');
          }
          return !snapshot.hasData
              ? SplashScreen()
              : snapshot.data
                  ? Navigator.of(context).pushReplacement(
                      MaterialPageRoute(builder: (context) => HomePage()))
                  : Navigator.of(context).pushReplacement(
                      MaterialPageRoute(builder: (context) => FirstScreen()));
        },
      ),
    );
  }

It won't work of course, since return values are not a Widget. Any solution?

Edit: Thanks to Remi, I solved like this:

        @override
  void initState() {
    final MainModel model = ScopedModel.of(context);
    model.bootUp().then(
          (value) => Future.delayed(
                Duration(seconds: 1, milliseconds: 500),
                () {
                  Navigator.pushReplacement(
                      context,
                      MaterialPageRoute(
                          builder: (context) =>
                              value ? HomePage() : FirstScreen()));
                },
              ),
        );
    super.initState();
  }

Upvotes: 4

Views: 2162

Answers (1)

Rémi Rousselet
Rémi Rousselet

Reputation: 277037

Simply do not use FututeBuilder and manipulate the Future directly:

Future future;
future.then((value) {
  Navigator.pushNamed(context, "/foo");
});

Bear in mind that you should not do this within the build method. Do this where you create your Future, typically initState

Upvotes: 5

Related Questions