【问题标题】:How to solve navigator problem on flutter?如何解决颤振上的导航器问题?
【发布时间】:2021-06-12 07:51:43
【问题描述】:

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

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"))));
  }
}

【问题讨论】:

标签: android flutter


【解决方案1】:

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

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

兄弟姐妹与孩子

这是因为您的 ElevatedButton 是 MyApp 小部件的子代,而不是 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 的工作,无论你给它什么,its 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。

【讨论】:

    【解决方案2】:

    你必须分开 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"))));
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-01
      • 1970-01-01
      • 2022-08-22
      • 1970-01-01
      • 2021-09-28
      • 2019-11-20
      • 2020-07-14
      • 2022-01-12
      • 2019-06-01
      相关资源
      最近更新 更多