简体   繁体   中英

How to create Flutter route for Stateful Widget?

I'm getting the Navigator operation requested with a context that does not include a Navigator. error log for my Flutter app. All the examples I see are for "Stateless" widgets so I think this may be the issue or my code? How can I route to my LoginPage ? Here is my code without any Navigator or route...

 void main() {
      runApp(new MyApp());
    }

    final googleSignIn = new GoogleSignIn();
    final fb = FirebaseDatabase.instance.reference();
    final auth = FirebaseAuth.instance;

    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => new _MyAppState();
    }

    class _MyAppState extends State<MyApp> {
      String _platformVersion = 'Unknown';

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

      // Platform messages are asynchronous, so we initialize in an async method.
      initPlatformState() async {
        String platformVersion;
        // Platform messages may fail, so we use a try/catch PlatformException.
        try {
          platformVersion = await Myfavkpopflutter.platformVersion;
        } on PlatformException {
          platformVersion = 'Failed to get platform version.';
        }

        // If the widget was removed from the tree while the asynchronous platform
        // message was in flight, we want to discard the reply rather than calling
        // setState to update our non-existent appearance.
        if (!mounted) return;

        setState(() {
          _platformVersion = platformVersion;
        });
      }

      void MyFavAction() {
        setState(() {
          print("MYFAV");

    //      fb.child("messages").orderByValue().onChildAdded.listen((Event event) {
    //        print('Child added: ${event.snapshot.value}');
    //      });
        });
      }

      void SearchAction() {
        setState(() {
          print("Search");
        });
      }



      @override
      Widget build(BuildContext context) {
        if (auth.currentUser == null) {
          return new MaterialApp(
            routes: <String, WidgetBuilder>{
            '/settings': (BuildContext context) => new LoginPage(),
            },
            home: new Scaffold(
              backgroundColor: Colors.white70,
              appBar: new AppBar(
                title: new Text(
                  "MyFavKPop",
                  style: new TextStyle(
                      color: Colors.black,
                      fontWeight: FontWeight.bold,
                      fontSize: 25.00),
                ),
                backgroundColor: Colors.amber,
              ),
              body: new Container(
                  child: new Center(
                      child: new Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  new RaisedButton(
                    onPressed: MyFavAction,
                    color: Colors.lightBlue,
                    elevation: 20.00,
                    splashColor: Colors.amber,
                    child: new Text(
                      "MyFav KPOP",
                      style: new TextStyle(color: Colors.black, fontSize: 20.00),
                    ),
                  ),
                  new Padding(padding: new EdgeInsets.all(30.00)),
                  new RaisedButton(
                    onPressed: SearchAction,
                    color: Colors.lightBlue,
                    elevation: 20.00,
                    splashColor: Colors.amber,
                    child: new Text(
                      "MyFav SEARCH",
                      style: new TextStyle(color: Colors.black, fontSize: 20.00),
                    ),
                  ),
                  new Padding(padding: new EdgeInsets.all(30.00),
                  ),
                  new RaisedButton(
                    onPressed: SearchAction,
                    elevation: 20.00,
                    splashColor: Colors.amber,
                    color: Colors.lightBlue,
                    child: new Text(
                      "MyFav FRIENDS",
                      style: new TextStyle(color: Colors.black, fontSize: 20.00),
                    ),
                  ),
                  new Padding(
                    padding: new EdgeInsets.all(30.00),
                  ),
                  new RaisedButton(
                    onPressed: SearchAction,
                    elevation: 20.00,
                    splashColor: Colors.amber,
                    color: Colors.lightBlue,
                    child: new Text(
                      "MyFav CHAT",
                      style: new TextStyle(color: Colors.black, fontSize: 20.00),
                    ),
                  ),
                  new Padding(
                    padding: new EdgeInsets.all(30.00),
                  ),
                  new RaisedButton(
                    onPressed: SearchAction,
                    elevation: 20.00,
                    splashColor: Colors.amber,
                    color: Colors.lightBlue,
                    child: new Text(
                      "MyFav #1'S",
                      style: new TextStyle(color: Colors.black, fontSize: 20.00),
                    ),
                  )
                ],
              ))),
              floatingActionButton: new FloatingActionButton(
                  child: new Text(
                    "Log Out",
                    style: new TextStyle(fontWeight: FontWeight.bold, fontSize: 12.00),
                  ),
                  onPressed: () => Navigator.of(context).pushNamed('/settings'),,
            ),
          ));
        } 
      }
    }

    class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Login / Signup"),
      ),
      body: new Container(
        child: new Center(
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new TextField(
                decoration: new InputDecoration(
                    hintText: "E M A I L    A D D R E S S"),
              ),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new TextField(
                obscureText: true,
                decoration:
                new InputDecoration(hintText: "P A S S W O R D"),
              ),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new TextField(
                decoration:
                new InputDecoration(hintText: "U S E R N A M E"),
              ),
              new RaisedButton(
                onPressed: null,
                child: new Text("SIGNUP"),
              ),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new RaisedButton(
                onPressed: null,
                child: new Text("LOGIN"),
              ),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new RaisedButton(
                onPressed: null,
                child: new Text("Facebook"),
              ),
              new Padding(padding: new EdgeInsets.all(5.00)),
              new RaisedButton(
                onPressed: null,
                child: new Text("Google"),
              )
            ],
          ),
        ),
        margin: new EdgeInsets.all(15.00),
      ),
    );
  }
}

**** EDIT Here is the error log I'm getting...

══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════ 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.

════════════════════════════════════════════════════════════════════════════════════════════════════

You stated in the title that your problem is navigating to a StatefulWidget while in your post you are asking about how to navigate to a StatelessWidget LoginPage.

Anyhow, you should be able to implement navigating the same way regardless of the state matter.

Try to follow the following flow which is taken from an app I am working on.

//Local Imports
//MyTabs.dart is where I define my home page which is a StatefulWidget with TabBarView 
import 'MyTabs.dart' as first;

.....

//My main function where I start my app

    void main() {
      runApp( new MaterialApp(
        home: new SignIn(),
        routes: <String, WidgetBuilder>{
          "/mytabs" : (BuildContext context)=> new first.MyTabs(),
          //add more routes here
        },

      ));
    }

My app starts with a SignIn page, I have created a simpler one than I have to show the idea

class SignIn extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  return new Scaffold(
    appBar: new AppBar(
      title: new Text("Sign In"),
    ),
    body: new IconButton(icon: new Icon(Icons.arrow_forward), onPressed: (){Navigator.of(context).pushNamed("/mytabs");}),
  )

I hope I was of any help, try to follow this flow in your code and let me know how it went.

Navigator.of(context).push(new MaterialPageRoute(builder: 
                   (BuildContext context) => new MyTabs()));

For navigation, we can use the above code also.

This error has nothing to do with stateful or stateless routes. You can look at my answer here for a working example.

By the way: I can't find your call to Navigator in your code. How and where do you call push?

edit

You should always only have one MaterialApp in your applications. You can provide various routes to one MaterialApp (see my example).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM