【问题标题】:Is there a way to configure willPopScope to catch a custom pop navigation in flutter?有没有办法配置 willPopScope 以捕捉自定义弹出导航?
【发布时间】:2020-02-26 19:40:57
【问题描述】:

有没有办法配置 willPopScope 来捕获自定义弹出导航,如下所示?我有一个带有 onPressed 的自定义 Raisedbutton 小部件可以导航回上一页。

但是 willPopScope 没有像 AppBar 后退按钮那样捕获导航。我不确定这是否可能。请指教。谢谢!

WillPopScope(
 child: Scaffold(
  body: Container(
   child: Center(
    child: RaisedButton(
     onPressed:(){
      return Navigator.pop(context);
     },
     child: Text("Go Back),
    ),
   ),
  ),
 ),
 onWillPop: () async {
  // code to show a modal
 }
);

【问题讨论】:

  • 如果用户弹出屏幕,您是否尝试显示模式?像“你确定”那种模态?或者您想在之前的屏幕上显示一些内容?
  • @MarianoZorrilla 是的,我试图展示一个“你确定”的模式。当点击应用栏上的后退按钮或手机上的实际后退按钮时,它可以工作,但不适用于屏幕上的此自定义后退按钮。
  • 我放弃了一个解决方案,如果该解决方案有效,请告诉我。

标签: flutter navigation alert


【解决方案1】:

这是实现目标的完整示例。 WillPopScope 需要maybePop 调用才能执行您的逻辑:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Jump To Next Screen'),
          onPressed: () => Navigator.of(context)
              .push(MaterialPageRoute(builder: (_) => ModalScreen())),
        ),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

class ModalScreen extends StatefulWidget {
  @override
  _ModalScreenState createState() => _ModalScreenState();
}

class _ModalScreenState extends State<ModalScreen> {
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      child: Scaffold(
        appBar: AppBar(
          leading: InkResponse(
            child: Icon(Icons.arrow_back),
            onTap: () => Navigator.of(context).maybePop(),
          ),
        ),
        backgroundColor: Colors.blue,
        body: Center(
          child: RaisedButton(
            child: Text('Let\'s go back'),
            onPressed: () {
              Navigator.of(context).maybePop();
            },
          ),
        ),
      ),
      onWillPop: () => _willPop(context),
    );
  }

  Future<bool> _willPop(BuildContext context) {
    final completer = Completer<bool>();
    showModalBottomSheet(
        context: context,
        builder: (buildContext) {
          return SizedBox(
            height: 200,
            child: Column(
              children: [
                Padding(
                  padding: const EdgeInsets.symmetric(vertical: 20),
                  child: Text('Are you sure?'),
                ),
                MaterialButton(
                    child: Text('YES'),
                    onPressed: () {
                      completer.complete(true);
                      Navigator.of(context).pop();
                    }),
                MaterialButton(
                    child: Text('NO'),
                    onPressed: () {
                      completer.complete(true);
                    }),
              ],
            ),
          );
        });

    return completer.future;
  }
}

一旦您为您的模态框返回true,您还需要弹出屏幕,因为模态框有自己的上下文需要被弹出。

最终结果如下:

【讨论】:

  • 很好的解决方案!但是,需要进行一次小的更正,当用户单击 NO 时,然后单击 completer.complete(false); 而不是 true
  • 他也想关闭弹出窗口,这就是这样做的方式。对于确认,我有一个额外的弹出窗口也可以关闭屏幕。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-27
  • 2011-09-04
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
  • 2022-08-09
  • 1970-01-01
相关资源
最近更新 更多