Maciek
Maciek

Reputation: 235

flutter Navigator in initState, not working

i have code like this from the internet, and my is not working:

class _StartingAnimationState extends State<StartingAnimation>{

  @override
  void initState() {
  Future.delayed(Duration(seconds: 4),(){
    Navigator.push(context, MaterialPageRoute(builder: (context) {
      return mainWindow();
    }));
  });
super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SizedBox(height: 300,width: 300, child: Lottie.asset("assets/lottie/login.json")),             
      );
  }
}

I got error:

[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Navigator operation requested with a context that does not include a Navigator.

and

The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.

I want my program to show animation for some time, and then navigate to other screen

Upvotes: 2

Views: 4043

Answers (4)

Anton Starcev
Anton Starcev

Reputation: 1258

Suggested solution is hucky:

Future.delayed(Duration(seconds: 4), () {

Best way was suggested in Flutter Redirect to a page on initState

SchedulerBinding.instance.addPostFrameCallback((_) {
  Navigator.of(context).pushNamed("login");
});

Upvotes: 0

Jitesh Mohite
Jitesh Mohite

Reputation: 34210

Why it's not working?

The MaterialApp configures the top-level Navigator to search for navigation routes in order:

  1. For the / route, the home property, if non-null, is used.

  2. Otherwise, the routes table is used, if it has an entry for the route.

  3. Otherwise, onGenerateRoute is called, if provided. It should return a non-null value for any valid route not handled by home and routes.

  4. Finally if all else fails onUnknownRoute is called.

That's why error comes when the above approach did not follow Unhandled Exception: Navigator operation requested with a context that does not include a Navigator.

Solution!!!

Wrap StartingAnimation with MaterialApp

runApp(MaterialApp(home: StartingAnimation()));

Note: This only happens when navigation is done on the route widget, if done on other widgets/screens, it will not occur as MaterialApp already initialized as everyone added at the top.

Upvotes: 0

Maciek
Maciek

Reputation: 235

i find answer for eanyone who will find this question

answer is:

i didnt put MaterialApp in my main:

runApp(MaterialApp(home: StartingAnimation()));

and also i saw mistake in my initState:

@override
  void initState() {
    super.initState();
  Future.delayed(Duration(seconds: 4),(){
    Navigator.push(context, MaterialPageRoute(builder: (context) {
      return mainWindow();
    }));
  });
  }

Upvotes: 1

Andrej
Andrej

Reputation: 3225

You can't push a new route in initState. How ever you can register a post frame callback that can run a function. In you build method, before the return statement:

WidgetsBinding.instance.addPostFrameCallback((_){
Future.delayed(Duration(seconds: 4),(){
    Navigator.push(context, MaterialPageRoute(builder: (context) {
      return mainWindow();
    }));
  });
});

return MaterialApp(
      home: SizedBox(height: 300,width: 300, child: Lottie.asset("assets/lottie/login.json")),
          //home: SizedBox(height: 300,width: 300, child: Lottie.asset("assets/lottie/login.json")),
      );

Upvotes: 2

Related Questions