实施导航器时发生异常。请求的导航器操作的上下文不包括导航器

时间:2018-08-16 21:01:53

标签: flutter

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

这是我得到的例外:

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"),

      ),
    ),
    );
  }
}

我正在寻找有关我需要在哪里实现带有代码段的Navigator小部件引用的输入。感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您在这里做错了几件事。首先是您有多个MaterialApp实例。您应该永远只有其中之一。

下一个问题是,在您的button1方法中,您正在使用小部件的上下文来找到Navigator。但是由于导航器是在该小部件中构建的,因此找不到它。本质上,这是您所使用的上下文:

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

当您执行Navigator.of(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"),
      ),
    );
  }
}