Flutter 颤振导航,重新打开页面,而不是再次推

Flutter 颤振导航,重新打开页面,而不是再次推,flutter,mobile-application,flutter-navigation,Flutter,Mobile Application,Flutter Navigation,我是个新手,我正在开发一个有多个屏幕的应用程序 我想知道如何阻止颤振创建同一路线的多个屏幕, 例如,我有第1页和第2页,如果我点击按钮导航到第2页,然后再次点击同一按钮,应用程序将弹出一个新的第2页的屏幕,我将看到两次,如果我点击返回按钮,它将把我送回第一个创建的第2页 是否有一种方法可以只创建一次每个页面,然后在它已经被推到堆栈中时重新打开它 我正在使用Navigator.push进行所有导航您应该使用Navigator.pushReplacement()。以下是文件: 总之,当您调用push

我是个新手,我正在开发一个有多个屏幕的应用程序

我想知道如何阻止颤振创建同一路线的多个屏幕, 例如,我有第1页和第2页,如果我点击按钮导航到第2页,然后再次点击同一按钮,应用程序将弹出一个新的第2页的屏幕,我将看到两次,如果我点击返回按钮,它将把我送回第一个创建的第2页

是否有一种方法可以只创建一次每个页面,然后在它已经被推到堆栈中时重新打开它


我正在使用
Navigator.push
进行所有导航

您应该使用
Navigator.pushReplacement()
。以下是文件:


总之,当您调用
pushReplacement
时,它会推送一个新页面,但也会处理上一个页面。现在,当您按下“后退”按钮时,它会将您带回第1页。

使用简单的逻辑

  • 如果新页面与当前页面相同,则使用
    Navigator.push(上下文、路由)

  • 如果新页面不同,则使用
    Navigator.pushReplacement(上下文、路线)


  • 如果您使用的是命名路由,则

  • 与当前页面相同,使用
    Navigator.pushNamed(上下文,名称)
  • 不同的页面,使用
    Navigator.pushreplacementname(上下文,名称)

  • 完整的代码示例

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: SO(),
        );
      }
    }
    
    class SO extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: PageOne(),
        );
      }
    }
    
    class PageOne extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Page 1'),
          ),
          backgroundColor: Colors.amber,
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                RaisedButton(
                  onPressed: () {
                    print('creating replacement page 1');
                    Navigator.pushReplacement(context, MaterialPageRoute(builder: (BuildContext context) {
                      return PageOne();
                    }));
                  },
                  child: Text('Go to page 1'),
                ),
                RaisedButton(
                  onPressed: () {
                    print('creating new page 2');
                    Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
                      return PageTwo();
                    }));
                  },
                  child: Text('Go to page 2'),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class PageTwo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Page 2'),
          ),
          backgroundColor: Colors.brown,
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                RaisedButton(
                  onPressed: () {
                    print('creating new page 1');
                    Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) => PageOne()));
                  },
                  child: Text('Go to page 1'),
                ),
                RaisedButton(
                  onPressed: () {
                    print('creating replacement page 2');
                    Navigator.pushReplacement(context, MaterialPageRoute(builder: (BuildContext context) => PageTwo()));
                  },
                  child: Text('Go to page 2'),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    类MyApp扩展了无状态小部件{
    @凌驾
    小部件构建(构建上下文){
    返回材料PP(
    home:那么(),
    );
    }
    }
    类因此扩展了无状态小部件{
    @凌驾
    小部件构建(构建上下文){
    返回脚手架(
    正文:PageOne(),
    );
    }
    }
    类PageOne扩展了无状态小部件{
    @凌驾
    小部件构建(构建上下文){
    返回脚手架(
    appBar:appBar(
    标题:正文(“第1页”),
    ),
    背景颜色:Colors.amber,
    正文:中(
    子:列(
    mainAxisSize:mainAxisSize.min,
    儿童:[
    升起的按钮(
    已按下:(){
    打印(“创建替换页1”);
    pushReplacement(上下文,MaterialPage路由(生成器:(BuildContext上下文){
    返回PageOne();
    }));
    },
    子项:文本(“转到第1页”),
    ),
    升起的按钮(
    已按下:(){
    打印(“创建新页面2”);
    push(上下文,MaterialPage路由(生成器:(BuildContext){
    返回PageTwo();
    }));
    },
    子项:文本(“转到第2页”),
    ),
    ],
    ),
    ),
    );
    }
    }
    类PageTwo扩展了无状态小部件{
    @凌驾
    小部件构建(构建上下文){
    返回脚手架(
    appBar:appBar(
    标题:正文(“第2页”),
    ),
    背景颜色:Colors.brown,
    正文:中(
    子:列(
    mainAxisSize:mainAxisSize.min,
    儿童:[
    升起的按钮(
    已按下:(){
    打印(“创建新页面1”);
    push(context,MaterialPageRoute(builder:(BuildContext context)=>PageOne());
    },
    子项:文本(“转到第1页”),
    ),
    升起的按钮(
    已按下:(){
    打印(“创建替换页2”);
    pushReplacement(context,MaterialPageRoute(builder:(BuildContext context)=>PageTwo());
    },
    子项:文本(“转到第2页”),
    ),
    ],
    ),
    ),
    );
    }
    }
    
    这些答案不正确
    PushReplacement
    仍将创建小部件的新实例。如果您在
    RouteA
    中有一个可滚动的列表,并且在导航到
    RouteB
    之前滚动该列表,那么识别该列表非常简单。当您
    按下替换(RouteA)
    时,您将看到滚动位置已更改为其初始状态。这是因为实例化了一个新的小部件,而这不是您想要的行为


    您应该使用之前JoaoSoares在第2页按钮上回答的
    popUntil
    ,是否要返回到第1页?如果是这样,您应该只使用Navigator.of(context.pop();它将关闭第2页并返回到第1页,而不创建新视图。在第2页上,该按钮不应可见。将导航视为一个堆栈。如果再次按下page2,堆栈上将有两个page2小部件实例。例如,对于抽屉,在返回到现有页面之前,您不一定要弹出所有页面。这样做,您将销毁导航堆栈的所有页面,以便只返回一个页面。为了一个而牺牲一切…^^我希望有一个方法来显示一个页面,如果它存在。。。