简体   繁体   English

颤振导航器不起作用

[英]Flutter Navigator not working

I have app with two screens, and I want to make push from 1st to second screen by pressing button.我有两个屏幕的应用程序,我想通过按下按钮从第一个屏幕推送到第二个屏幕。

Screen 1屏幕 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屏幕 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.用于从 Navigator 推送或弹出路由的上下文必须是作为 Navigator 小部件后代的小部件的上下文。

Another exception was thrown: Navigator operation requested with a context that does not include a Navigator.引发了另一个异常:使用不包含导航器的上下文请求的导航器操作。

What is wrong?怎么了?

Think of the widgets in Flutter as a tree, with the context pointing to whichever node is being built with the build function.将 Flutter 中的小部件视为一棵树,上下文指向使用 build 函数构建的任何节点。 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.因此,当您使用上下文来查找导航器时,您正在使用不在导航器下的 MainScreen 的上下文。

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.您可以创建一个新的 Stateless 或 Stateful Widget 子类来包含您的 Center + FlatButton,因为它们中的构建函数将指向该级别,或者您可以使用Builder并定义builder回调(它具有指向Builder) 返回 Center + FlatButton。

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 1) Route传递给 Navigator.of(context)的上下文下面定义 - @rmtmackenzie 解释的场景

2) The Route is defined on the sibling branch eg 2) Route 定义在同级分支上,例如

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.如果我们想从 Navigation 小部件调度路由,我们必须知道对 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 .https://docs.flutter.io/flutter/widgets/GlobalKey-class.html Use it only where there is no way to get it from Navigator.of(context).仅在无法从 Navigator.of(context) 获取它的地方使用它。

To use a GlobalKey inside the MaterialApp define navigatorKey要在 MaterialApp 中使用 GlobalKey 定义 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 的任何位置调用

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

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

Just make the MaterialApp class in main method as this example只需在 main 方法中创建 MaterialApp 类作为这个例子

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

it works fine for me, I hope it will work with you它对我有用,我希望它对你有用

There is an another very different work around about this issue, If you are using Alarm Manager (Android) , and open back to your Application.关于这个问题,还有另一个非常不同的工作,如果您使用的是Alarm Manager (Android) ,然后打开回您的应用程序。 If you haven't turned on the screen before navigation, the navigator will never work.如果您在导航前没有打开屏幕,导航器将永远无法工作。 Although this is a rare usage, I think It should be a worth to know.虽然这是一个很少见的用法,但我认为它应该是值得知道的。

Make sure route table mentioned in same context:确保在同一上下文中提到路由表:

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
       home: FutureBuilder(future: _isUserLoggedIn(),
                   builder: (ctx, loginSnapshot) => 
                   loginSnapshot.connectionState == ConnectionState.waiting ?
                   SplashScreen() : loginSnapshot.data == true ?  AppLandingScreen(): SignUpScreen()
                ),
       routes: {
         AppLandingScreen.routeName: (ctx) => AppLandingScreen(),
      },

    );



  }

I faced this issue because i define route table in different build method.我遇到这个问题是因为我用不同的构建方法定义了路由表。

Am a newbie and have spent two days trying to get over the Navigtor objet linking to a black a screen.我是新手,花了两天时间试图解决链接到黑色屏幕的 Navigtor 对象。

The issue causing this was dublicated dummy data .导致这种情况的问题是重复的虚拟数据 Find Bellow the two dummny data blocks:找到 Bellow 两个虚拟数据块:

**Problematic data **- duplicate assets/image:

_buildFoodItem('assets/plate1.png', 'Salmon bowl', '\$24'),
_buildFoodItem('assets/plate2.png', 'Spring bowl', '\$13'),
_buildFoodItem('assets/plate1.png', 'Salmon bowl', '\$24'),
_buildFoodItem('assets/plate5.png', 'Berry bowl', '\$34'),

**Solution **- after eliminating duplicated image argument:
_buildFoodItem('assets/plate1.png', 'Salmon bowl', '\$24'),
_buildFoodItem('assets/plate2.png', 'Spring bowl', '\$13'),
_buildFoodItem('assets/plate6.png', 'Avocado bowl', '\$34'),

I hope this helps someone,,,,,,,我希望这可以帮助别人,,,,,,,

If the navigator is not working, it can be due to many reasons but the major one is that the navigator not finds the context.如果导航器不工作,可能有多种原因,但主要的一个是导航器没有找到上下文。 So, to solve this issue try to wrap your widget inside Builder because the builder has its own context...因此,要解决此问题,请尝试将您的小部件包装在Builder 中,因为构建器有自己的上下文...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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