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

Posted

技术标签:

【中文标题】Flutter 导航,重新打开页面而不是再次推送【英文标题】:Flutter navigation, reopen page instead of pushing it again 【发布时间】:2020-04-14 20:37:48 【问题描述】:

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

我想知道如何阻止颤振创建同一路线的多个屏幕, 例如我有 Page 1Page 2,如果我点击按钮导航到第 2 页并再次点击同一个按钮,应用程序将推送一个新屏幕第 2 页,我将获得两次,如果我点击返回按钮,它会将我返回到第一个创建的 第 2 页

有没有办法让每个页面只创建一次,如果它已经被推入堆栈,则重新打开它?

我的所有导航都使用Navigator.push

【问题讨论】:

在第 2 页的按钮上,您要返回第 1 页吗?如果是这样,您应该只使用 Navigator.of(context).pop();它将关闭第 2 页并返回第 1 页而不创建新视图。 该按钮在 page2 上时不可见。将导航视为堆栈。如果再次推送 page2,堆栈上将有两个 page2 小部件实例。 这个问题你解决了吗???? 【参考方案1】:

这些答案不正确。 PushReplacement 仍将创建小部件的新实例。识别RouteA 中是否有可滚动列表并在导航到RouteB 之前滚动它非常简单。当您 pushReplacement(RouteA) 时,您会看到滚动位置已更改为初始状态。那是因为实例化了一个新的小部件,这不是您想要的行为。

您应该使用 popUntil,正如 JoaoSoares 之前回答的那样

【讨论】:

例如,在抽屉的情况下,您不一定要弹出所有页面,直到返回到现有页面。通过这样做,您将销毁导航堆栈的所有页面,以便只返回一个。为一个人牺牲一切... ^^ 我希望有一种方法可以显示页面(如果存在)...【参考方案2】:

这里使用一个简单的逻辑

    如果新页面与当前页面相同,则使用Navigator.push(context,route)

    如果新页面不同,则使用Navigator.pushReplacement(context,route)


如果你使用命名路由,那么对于

    与当前页面相同,使用Navigator.pushNamed(context,name)。 不同的页面,使用Navigator.pushReplacementNamed(context,name)

完整的代码示例

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'),
            ),
          ],
        ),
      ),
    );
  

【讨论】:

【参考方案3】:

您应该使用Navigator.pushReplacement()。以下是文档:https://api.flutter.dev/flutter/widgets/NavigatorState/pushReplacement.html

总而言之,当您调用pushReplacement 时,它会推送一个新页面,但也会处理前一个页面。现在,当您按下返回按钮时,它应该会带您回到第 1 页。

【讨论】:

以上是关于Flutter 导航,重新打开页面而不是再次推送的主要内容,如果未能解决你的问题,请参考以下文章

打开定位服务而不导航到设置页面?飞镖

Flutter 导航推送,同时保持 Appbar 不变

怎么让网站的导航打开时是新网页? 例如 论坛 我点下他就重新跳出一个页面出来,而不是继续在原网显示的.谢

每次推送新路线时,都会再次显示最后的 Flutter SnackBar

如果在 WebView Flutter 中导航失败,则重新加载页面

导航 PopUpToInclusive 不起作用?重新打开应用程序时,它会打开登录片段而不是电子邮件登录片段