【问题标题】:Flutter navigation, reopen page instead of pushing it againFlutter 导航,重新打开页面而不是再次推送
【发布时间】:2023-04-04 01:56:01
【问题描述】:

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

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

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

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

【问题讨论】:

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

标签: flutter mobile-application flutter-navigation


【解决方案1】:

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

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

【讨论】:

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

这里使用一个简单的逻辑

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

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


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

  1. 与当前页面相同,使用Navigator.pushNamed(context,name)
  2. 不同的页面,使用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 页。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-24
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 2011-12-31
      • 2019-10-19
      • 1970-01-01
      相关资源
      最近更新 更多