如何解决颤振上的导航器问题?

时间:2021-03-15 01:41:44

标签: android flutter

我正在尝试使用该按钮制作另一个页面,但是在调试此代码后,出现了名为“下一步”的按钮,但是当我单击该按钮时,没有任何反应,并且此错误出现在“导航器操作请求的上下文中不包括导航器。” 有人可以帮我吗? 非常感谢:)

import 'package:flutter/material.dart';

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

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

class _MyAppState extends State<MyApp> {
  TextEditingController nameController = TextEditingController();
  TextEditingController ageController = TextEditingController();
  TextEditingController addressController = TextEditingController();
  TextEditingController weightController = TextEditingController();
  TextEditingController heightController = TextEditingController();
  TextEditingController traitController = TextEditingController();
  TextEditingController appearanceController = TextEditingController();

  String fullName = '';
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.pink,
      ),
      home: Scaffold(
          appBar: AppBar(
            title: Text('Input Information'),
          ),
          drawer: Drawer(
            child: ListView(
              padding: EdgeInsets.zero,
              children: <Widget>[
                DrawerHeader(
                  child: Text('Drawer Header'),
                  decoration: BoxDecoration(
                    color: Colors.purple,
                  ),
                ),
                ListTile(
                  title: Text('Item 1'),
                  onTap: () {
                    Navigator.pop(context);
                  },
                ),
                ListTile(
                  title: Text('Item 2'),
                  onTap: () {
                    Navigator.pop(context);
                  },
                ),
              ],
            ),
          ),
          body: Center(
              child: Column(children: <Widget>[
            Container(
                margin: EdgeInsets.all(20),
                child: TextField(
                  controller: nameController,
                  decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Full Name',
                  ),
                )),
            Container(
                margin: EdgeInsets.all(20),
                child: TextField(
                  controller: ageController,
                  decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Age',
                  ),
                )),
            Container(
                margin: EdgeInsets.all(20),
                child: TextField(
                  controller: addressController,
                  decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Address',
                  ),
                )),
            Container(
                margin: EdgeInsets.all(20),
                child: TextField(
                  controller: weightController,
                  decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Weight',
                  ),
                )),
            Container(
                margin: EdgeInsets.all(20),
                child: TextField(
                  controller: heightController,
                  decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Height',
                  ),
                )),
            Container(
                margin: EdgeInsets.all(20),
                child: TextField(
                  controller: traitController,
                  decoration: InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Unique Trait',
                  ),
                )),
            // Container(
            //     margin: EdgeInsets.all(20),
            //     child: TextField(
            //       controller: appearanceController,
            //       decoration: InputDecoration(
            //         border: OutlineInputBorder(),
            //         labelText: 'Apperance',
            //       ),
            //     )),
            ElevatedButton(
              child: Text('Next'),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SecondRoute()),
                );
              },
            ),
            Container(
              margin: EdgeInsets.all(20),
              child: Text(fullName),
            )
          ]))),
    );
  }
}

class SecondRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Camera"),
        ),
        body: Center(
            child: ElevatedButton(
                onPressed: () {
                  Navigator.pop(context);
                },
                child: Text("Back"))));
  }
}

2 个答案:

答案 0 :(得分:0)

你必须分离 MaterialApp 。为页面创建单独的类。只有这样您才能从一个页面导航到另一个页面。

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(
      theme: ThemeData(
        primarySwatch: Colors.pink,
      ),
      home:FirstPage(),
    );
  }
}

class FirstPage  extends StatefulWidget{
  @override
  _FirstPageState createState() => _FirstPageState();
}

class _FirstPageState extends State<FirstPage> {
   TextEditingController nameController = TextEditingController();

  TextEditingController ageController = TextEditingController();

  TextEditingController addressController = TextEditingController();

  TextEditingController weightController = TextEditingController();

  TextEditingController heightController = TextEditingController();

  TextEditingController traitController = TextEditingController();

  TextEditingController appearanceController = TextEditingController();

  String fullName = '';

    Widget build(BuildContext context){
      return  Scaffold(
          appBar: AppBar(
            title: Text('Input Information'),
          ),
          drawer: Drawer(
            child: ListView(
              padding: EdgeInsets.zero,
              children: <Widget>[
                DrawerHeader(
                  child: Text('Drawer Header'),
                  decoration: BoxDecoration(
                    color: Colors.purple,
                  ),
                ),
                ListTile(
                  title: Text('Item 1'),
                  onTap: () {
                    Navigator.pop(context);
                  },
                ),
                ListTile(
                  title: Text('Item 2'),
                  onTap: () {
                    Navigator.pop(context);
                  },
                ),
              ],
            ),
          ),
          body: SingleChildScrollView(
            child: Center(
                child: Column(children: <Widget>[
              Container(
                  margin: EdgeInsets.all(20),
                  child: TextField(
                    controller: nameController,
                    decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Full Name',
                    ),
                  )),
              Container(
                  margin: EdgeInsets.all(20),
                  child: TextField(
                    controller: ageController,
                    decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Age',
                    ),
                  )),
              Container(
                  margin: EdgeInsets.all(20),
                  child: TextField(
                    controller: addressController,
                    decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Address',
                    ),
                  )),
              Container(
                  margin: EdgeInsets.all(20),
                  child: TextField(
                    controller: weightController,
                    decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Weight',
                    ),
                  )),
              Container(
                  margin: EdgeInsets.all(20),
                  child: TextField(
                    controller: heightController,
                    decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Height',
                    ),
                  )),
              Container(
                  margin: EdgeInsets.all(20),
                  child: TextField(
                    controller: traitController,
                    decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Unique Trait',
                    ),
                  )),
              // Container(
              //     margin: EdgeInsets.all(20),
              //     child: TextField(
              //       controller: appearanceController,
              //       decoration: InputDecoration(
              //         border: OutlineInputBorder(),
              //         labelText: 'Apperance',
              //       ),
              //     )),
              ElevatedButton(
                child: Text('Next'),
                onPressed: () {
                   Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SecondRoute()),
                );
                },
              ),
              Container(
                margin: EdgeInsets.all(20),
                child: Text(fullName),
              )
            ])),
          ));
    }
}

class SecondRoute extends StatelessWidget {
//   static const String routes = 'second-page';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Camera"),
        ),
        body: Center(
            child: ElevatedButton(
                onPressed: () {
                  Navigator.pop(context);
                },
                child: Text("Back"))));
  }
}

答案 1 :(得分:0)

一种解决方案是将您的 ElevatedButton 包装在 Builder 小部件中。

                Builder(
                  builder: (context) => ElevatedButton(
                    child: Text('Next'),
                    onPressed: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(builder: (context) => SecondRoute()),
                      );
                    },
                  ),
                ),

兄弟姐妹与孩子

这是有效的,因为您的 ElevatedButtonMyApp 小部件的子代,而不是 MaterialApp 小部件的子代。 MaterialApp 为其子项提供默认 Navigator。但是,ElevatedButton 目前是 MaterialApp兄弟姐妹,而不是它的孩子(上下文)。

由于嵌套的 Dart 代码可以出现多长时间,因此很难看到这一点。

上下文层次结构

这是从层次结构方面查看问题中代码的另一种方式:

main
  MyApp(context)
    MaterialApp(theme, home, body) ← everything at this level is using MyApp context

您的 body: 参数 ↑ 扩展为 ↓ :

main
  MyApp(context)
    MaterialApp(theme, home, body: Center(container x6, ElevatedButton(context)))

...这意味着 ElevatedButton 得到 MyApp context

再往下一层:

main
  MyApp(context)
    MaterialApp(theme, home, body)
      Widgets on this level will use MaterialApp context

ElevatedButton 包裹在 Builder 中,将 ElevatedButton 下推一个级别。这是Builder's的工作,无论你付出什么, context级别的孩子。

因此使用 Builder 后,上面的内容变为:

main
  MyApp(context)
    MaterialApp(theme, home, body: Center(container x6, Builder))
                                                           ElevatedButton ← uses MaterialApp context

导航器(偷偷摸摸的)上下文

Navigator.push(context) 也很容易误解它是如何使用提供的 context。有关这方面的更多背景信息,请参阅我为类似问题撰写的 this answer,我在其中更详细地解释了 Navigator.of