Flutter - 导航到新屏幕并返回

Posted

技术标签:

【中文标题】Flutter - 导航到新屏幕并返回【英文标题】:Flutter - Navigate to a new screen and back 【发布时间】:2019-12-02 23:44:31 【问题描述】:

有人可以帮我处理 Flutter。

我正在尝试(导航到新屏幕并返回。)

按照此处的指南进行操作:

https://flutter.dev/docs/cookbook/navigation/navigation-basics

但我在这里遇到了这个错误:

另一个异常被抛出:导航器操作请求 不包含导航器的上下文。

这是我的简单 Flutter 代码:

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 new MaterialApp(
      title: 'Welcome',
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to view by view'),
        ),
        body: Center(
          child: Wrap(
            children: <Widget>[
              RaisedButton(
                child: Text('View 2'),
                onPressed: ()
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => SecondRoute()),
                  );
                ,
              )
            ],
          ),
        ),
      )
    );
  


class SecondRoute extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Route"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () 
            Navigator.pop(context);
          ,
          child: Text('Go back!'),
        ),
      ),
    );
  

谢谢!

【问题讨论】:

【参考方案1】:

奇怪的是,文档会推荐一种损坏的方法!只需将 MaterialApp 的主体提取到它自己的 Widget 中即可。代码如下:

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 new MaterialApp(
        title: 'Welcome',
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          appBar: AppBar(
            title: Text('Welcome to view by view'),
          ),
          body: FirstRoute(),
        )
    );
  


class FirstRoute extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Center(
      child: Wrap(
        children: <Widget>[
          RaisedButton(
            child: Text('View 2'),
            onPressed: ()
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => SecondRoute()),
              );
            ,
          )
        ],
      ),
    );
  



class SecondRoute extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Route"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () 
            Navigator.pop(context);
          ,
          child: Text('Go back!'),
        ),
      ),
    );
  

【讨论】:

显然已经报告了这个问题:github.com/flutter/flutter/issues/15919 您的代码有效,但我需要(扩展 State),以便我可以将按钮实时更新为变量 Text(),这就是为什么我有(class _MyAppState extends State ) 我这里需要这个 setState(() );在我的 RaisedButton【参考方案2】:

将需要访问 Navigator 的小部件包装到 Builder 中或将该子树提取到一个类中。并使用新的 BuildContext 访问 Navigator。

【讨论】:

【参考方案3】:

是的,在颤振示例中 MaterialApp 是

 runApp(MaterialApp(
    title: 'Navigation Basics',
    home: FirstRoute(),
  ));

在示例 FirstRoute 中,它与 MaterialApp 分开。这样做是因为如果我们将 FirstRoute 的内容直接放在 MaterialApp 中,那么它就没有 MaterialApp 的上下文,并且它无法访问 Navigator。

你有两个选择。

将 Scaffold 放置在它自己的无状态 Widget 中。

或者将脚手架包装在构建器小部件中以使 MaterialApp 上下文可用

class _MyAppState extends State<MyApp>

  @override
  Widget build(BuildContext context)
    return new MaterialApp(
      title: 'Welcome',
      debugShowCheckedModeBanner: false,
      home: Builder(builder: (BuildContext context) 
      return Scaffold(
        appBar: AppBar(
          title: Text('Welcome to view by view'),
        ),
        body: Center(
          child: Wrap(
            children: <Widget>[
              RaisedButton(
                child: Text('View 2'),
                onPressed: ()
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => SecondRoute()),
                  );
                ,
              )
            ],
          ),
        ),
      ))
    );
  

更多信息this answer

【讨论】:

以上是关于Flutter - 导航到新屏幕并返回的主要内容,如果未能解决你的问题,请参考以下文章

在不离开父屏幕的情况下导航到新屏幕

Flutter 导航返回主屏幕

Flutter Dropdown Button在屏幕导航期间不保存状态

基于是新登录还是返回用户在 Flutter 中导航屏幕

条码扫描后导航到新页面,不返回原始页面

在按钮单击 SwiftUI 时导航到新屏幕