Flutter Navigator无法正常工作

moo*_*der 8 dart flutter

我有两个屏幕的应用程序,我想按下按钮从第一个屏幕到第二个屏幕.

屏幕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()))
                    }
                )
            )
        )
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

屏幕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"),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

推动没有发生,我得到了这个

处理手势时抛出以下断言:使用不包含导航器的上下文请求导航器操作.用于从导航器推送或弹出路由的上下文必须是作为Navigator窗口小部件后代的窗口小部件的上下文.

引发了另一个异常:使用不包含导航器的上下文请求导航器操作.

怎么了?

Yah*_*hYa 15

只需在 main 方法中创建 MaterialApp 类作为这个例子

 void main() => runApp(MaterialApp(home: FooClass(),));
Run Code Online (Sandbox Code Playgroud)

它对我有用,我希望它对你有用

  • 漂亮优雅的解决方案。 (2认同)

rmt*_*zie 11

将Flutter中的小部件视为一棵树,上下文指向使用构建函数构建的任何节点.在你的情况下,你有

MainScreen    <------ context
  --> MaterialApp
   (--> Navigator built within MaterialApp)
      --> Scaffold
        --> App Bar
          --> ...
        --> Center
          --> FlatButton
Run Code Online (Sandbox Code Playgroud)

因此,当您使用上下文查找导航器时,您正在使用MainScreen的上下文,该上下文不在导航器下.

您可以创建一个新的Stateless或Stateful Widget子类来包含您的Center + FlatButton,因为其中的构建函数将指向该级别,或者您可以使用Builder并定义builder回调(其中包含指向Builder的上下文) )返回Center + FlatButton.


rob*_*ter 5

找不到路由的主要原因有两个。

1)路由传递给Navigator.of(context)的上下文下面定义-@rmtmackenzie解释的场景

2)路由是在同级分支上定义的例如

Root 

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

  -> Navigation (we want to dispatch from here)
Run Code Online (Sandbox Code Playgroud)

如果要从“导航”窗口小部件分派路线,则必须知道对NavigatorState的引用。具有全局引用非常昂贵,尤其是当您打算在树上移动小部件时。https://docs.flutter.io/flutter/widgets/GlobalKey-class.html。仅在无法从Navigator.of(context)获取它的地方使用它。

要在MaterialApp中使用GlobalKey,请定义navigatorKey

final navigatorKey = GlobalKey<NavigatorState>();

Widget build(BuildContext context) => MaterialApp {
    navigatorKey: navigatorKey
    onGenerateRoute : .....
};
Run Code Online (Sandbox Code Playgroud)

现在,您可以在应用中传递navigatorKey的任何位置调用

navigatorKey.currentState.push(....);
Run Code Online (Sandbox Code Playgroud)

刚刚发布了关于它的https://medium.com/@swav.kulinski/flutter-navigating-off-the-charts-e118562a36a5