代码之家  ›  专栏  ›  技术社区  ›  Darshan

实现导航器时发生异常。使用不包含导航器的上下文请求的导航器操作

  •  0
  • Darshan  · 技术社区  · 8 年前

    我开始玩颤振,并试图打开一个新的屏幕后,点击一个按钮,从主屏幕。我查看了之前提出的类似问题,并尝试遵循提供的解决方案,但不太确定如何以及在何处实现该解决方案。

    这是我得到的例外:

    Navigator operation requested with a context that does not include a Navigator.
    

    Navigator 小部件,但不知道如何解决它。以下是我的完整代码:

    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
    
        Widget phoneSection = Container(
          padding: const EdgeInsets.all(16.0),
          child: Row(
            children: <Widget>[Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[Container(
                  padding: const EdgeInsets.only(bottom: 8.0),
                  child: Text(
                    'Welcome To City',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
    
                    ),
                  ),
                )
                ],
              ),
            ),
            ],
          ),
        );
    
        Widget buttonSection = RaisedButton(
          child: const Text('Lets Take a Tour'),
          color: Theme.of(context).primaryColor,
          elevation: 4.0,
          splashColor: Colors.blueGrey,
          onPressed: () {
            Navigator.of(context).pushNamed('/screen2');
          },
        );
    
        return MaterialApp(
          title: 'ATG',
    
          home: Scaffold(
            appBar: AppBar(
              title: Text('Tour Guide'),
            ),
            body: ListView(
              children: <Widget>[Image.asset(
                'images/bkm.png',
                width: 600.0,
                height: 240.0,
                fit: BoxFit.cover,
              ),
    
              phoneSection,
              buttonSection,
              ],
            ),
          ),
          routes: <String, WidgetBuilder> {
            '/screen2' : (BuildContext context) => new Screen2(),
          },
        );
    
      }
    
      void button1(BuildContext context) {
        Navigator.of(context).pushNamed('/screen2');
      }
    }
    
    class Screen2 extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return MaterialApp(
          home: new Scaffold(
          appBar: new AppBar(
            title: new Text("Screen 2"),
    
          ),
        ),
        );
      }
    }
    

    我正在寻找关于我到底需要在哪里实现 带有代码段的小部件引用。谢谢你的帮助。

    1 回复  |  直到 8 年前
        1
  •  1
  •   rmtmckenzie    8 年前

    有几件事你做错了。首先是你有多个 MaterialApp

    下一期是你的 button1 方法,您使用小部件的上下文来查找 Navigator . 但是由于导航器是在这个小部件中构建的,所以它找不到它。这基本上就是您使用的上下文:

    MyApp    <---- Context
      MaterialApp
        (Navigator)
          Scaffold 
            ...
    

    当你做Navigator.of(context)的时候,它从当前的context开始,然后在树上。

    我建议你把你的应用程序分开,这样你就有一个MyApp小部件(或者你想叫它什么的)广告,然后每个屏幕都有小部件。通过使用Builder小部件可以在不使用它的情况下完成这项工作,但是无论如何分割构建函数是一个更好的实践。

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'ATG',
          home: HomeScreen(),
          routes: <String, WidgetBuilder>{
            '/screen2': (BuildContext context) => new Screen2(),
          },
        );
      }
    }
    
    class HomeScreen extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
    
        Widget phoneSection = Container(
          padding: const EdgeInsets.all(16.0),
          child: Row(
            children: <Widget>[
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Container(
                      padding: const EdgeInsets.only(bottom: 8.0),
                      child: Text(
                        'Welcome To City',
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    )
                  ],
                ),
              ),
            ],
          ),
        );
    
        Widget buttonSection = RaisedButton(
          child: const Text('Lets Take a Tour'),
          color: Theme.of(context).primaryColor,
          elevation: 4.0,
          splashColor: Colors.blueGrey,
          onPressed: () {
            Navigator.of(context).pushNamed('/screen2');
          },
        );
    
        return Scaffold(
          appBar: AppBar(
            title: Text('Tour Guide'),
          ),
          body: ListView(
            children: <Widget>[
              Image.asset(
                'images/bkm.png',
                width: 600.0,
                height: 240.0,
                fit: BoxFit.cover,
              ),
              phoneSection,
              buttonSection,
            ],
          ),
        );
      }
    
      void button1(BuildContext context) {
        Navigator.of(context).pushNamed('/screen2');
      }
    }
    
    class Screen2 extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text("Screen 2"),
          ),
        );
      }
    }