Flutter Navigator not working

2019-04-29 05:29发布

问题:

I have app with two screens, and I want to make push from 1st to second screen by pressing button.

Screen 1

import 'package:flutter/material.dart';
import './view/second_page.dart';

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new MainScreen();
  }
}

class MainScreen extends State<MyApp> {

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

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        home: new Scaffold(
            appBar: new AppBar(
                title: new Text("Title")
            ),
            body: new Center(
                child: new FlatButton(child: new Text("Second page"),
                    onPressed: () {
                      Navigator.push(context,
                          new MaterialPageRoute(
                              builder: (context) => new SecondPage()))
                    }
                )
            )
        )
    );
  }
}

Screen 2

import 'package:flutter/material.dart';

class SecondPage extends StatefulWidget {

  @override
  State<StatefulWidget> createState() {
    return new SecondPageState();
  }
}


class SecondPageState extends State<SecondPage> {

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

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Title"),
      ),
      body: new Center(
        child: new Text("Some text"),
      ),
    );
  }
}

Push not happening and I got this

The following assertion was thrown while handling a gesture: Navigator operation requested with a context that does not include a Navigator. 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.

Another exception was thrown: Navigator operation requested with a context that does not include a Navigator.

What is wrong?

回答1:

Think of the widgets in Flutter as a tree, with the context pointing to whichever node is being built with the build function. In your case, you have

MainScreen    <------ context
  --> MaterialApp
   (--> Navigator built within MaterialApp)
      --> Scaffold
        --> App Bar
          --> ...
        --> Center
          --> FlatButton

So when you're using the context to find the Navigator, you're using a context for the MainScreen which isn't under the navigator.

You can either make a new Stateless or Stateful Widget subclass to contain your Center + FlatButton, as the build function within those will point at that level instead, or you can use a Builder and define the builder callback (which has a context pointing at the Builder) to return the Center + FlatButton.



回答2:

There are two main reasons why the route cannot be found.

1) The Route is defined below the context passed to Navigator.of(context) - scenario which @rmtmackenzie has explained

2) The Route is defined on the sibling branch e.g.

Root 

  -> Content (Routes e.g. Home/Profile/Basket/Search)

  -> Navigation (we want to dispatch from here)

If we want to dispatch a route from the Navigation widget, we have to know the reference to the NavigatorState. Having a global reference is expensive, especially when you intend to move widget around the tree. https://docs.flutter.io/flutter/widgets/GlobalKey-class.html. Use it only where there is no way to get it from Navigator.of(context).

To use a GlobalKey inside the MaterialApp define navigatorKey

final navigatorKey = GlobalKey<NavigatorState>();

Widget build(BuildContext context) => MaterialApp {
    navigatorKey: navigatorKey
    onGenerateRoute : .....
};

Now anywhere in the app where you pass the navigatorKey you can now invoke

navigatorKey.currentState.push(....);

Just posted about it https://medium.com/@swav.kulinski/flutter-navigating-off-the-charts-e118562a36a5



回答3:

just make the MaterialApp Class in main method as this example

 void main() => runApp(MaterialApp(home: FooClass(),));

it Works fine for me , I hope it Will work



标签: dart flutter