【问题标题】:How to close Scaffold's drawer after an item tap?物品点击后如何关闭脚手架的抽屉?
【发布时间】:2017-10-04 01:37:26
【问题描述】:

点击 Scaffold 抽屉中的某个项目后,我希望它自动隐藏。如何在 Flutter 中做到这一点?

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    Navigator.pop() 会将Drawer 路由从堆栈中弹出并使其关闭。

    【讨论】:

    • 但这意味着我需要将此调用添加到每个 onTap 处理程序,对吧?
    • 是的。如果代码重复困扰您,您可以将对 pop 的调用重构为共享私有方法。
    • 所以,如果我想同时打开一条新路线,我必须先关闭抽屉,然后再推另一个。抽屉的工作方式非常愚蠢。哈哈。我一直认为抽屉是脚手架的小部件,但似乎我肯定错了。 :(
    • 我很抱歉,但Navigator.pop() 在我的情况下没有关闭抽屉......(Navigator.pop(context)Navigator.pop(context, true) 也不这样做......我需要做什么为了通过选择其中一项来关闭抽屉?我的抽屉在 MaterialApp 内的 Scaffold 内...这有关系吗??
    • 看来 MaterialApp 确实引起了问题(因为缺少上下文)。我找到了解决方案from this link...
    【解决方案2】:
    【解决方案3】:

    关闭抽屉并导航到新路线的简写:

    Navigator.popAndPushNamed(context, '/newroute');

    【讨论】:

      【解决方案4】:

      首先创建一个 ScaffoldState 键

      GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
      
      Scaffold(
        key: _scaffoldKey,)
      

      现在您可以使用toggleDrawer() 方法打开和关闭抽屉。

      左侧抽屉

      toggleDrawer() async {
        if (_scaffoldKey.currentState.isDrawerOpen) {
          _scaffoldKey.currentState.openEndDrawer();
        } else {
          _scaffoldKey.currentState.openDrawer();
        }
      }
      

      右抽屉

      toggleDrawer() async {
        if (_scaffoldKey.currentState.isDrawerOpen) {
          _scaffoldKey.currentState.openDrawer();
        } else {
          _scaffoldKey.currentState.openEndDrawer();
        }
      }
      

      【讨论】:

      • 我觉得这是以编程方式管理抽屉的最佳答案
      • 如何关闭抽屉?
      • 很好的解决方案,但应该注意的是,如果抽屉放在“右侧”,这对抽屉不起作用。 Scaffold(endDrawer: Drawer())
      • @Matthew for endDrawer toggleDrawer() async { if (_scaffoldKey.currentState.isDrawerOpen) { _scaffoldKey.currentState.openDrawer(); } else { _scaffoldKey.currentState.openEndDrawer(); } }
      • 用于右侧抽屉 if (_scaffoldKey.currentState!.isEndDrawerOpen) { _scaffoldKey.currentState!.openDrawer(); } else { _scaffoldKey.currentState!.openEndDrawer(); }
      【解决方案5】:

      如果你只是想关闭Drawer,你可以使用以下任何一种:

      Navigator.pop(context);
      Navigator.of(context).pop();
      

      如果你想导航到一个新页面,你可以使用

      Navigator.popAndPushNamed(context, "/new_page");
      

      Navigator.pop(context);
      Navigator.push(context, MaterialPageRoute(builder: (_) => Page2()));
      

      【讨论】:

        【解决方案6】:

        对于最新的 Flutter 版本(我写这篇文章时是 v0.3.2),实现有所改变,Navigator.pop() 现在需要给定的上下文。

        Navigator.pop(context) 是关闭路由的典型用法。
        Navigator.pop(context, true) 是关闭返回结果的路由的用法。

        请参阅 Flutter 的食谱中的 Drawer Classexample

        【讨论】:

          【解决方案7】:

          这就是答案

          一流的

          GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
          

          小部件中的第二个

           Scaffold(key: _scaffoldKey,)
          

          代码第三

          if (_scaffoldKey.currentState.isDrawerOpen) {
            _scaffoldKey.currentState.openEndDrawer();
          }
          

          【讨论】:

            【解决方案8】:

            我认为 OP 可能想说的是,即使 Navigator.of(context).pop() 和 Navigator.pop(context) 应该可以工作,但他们不在他的情况下——我有同样的问题。

            在项目的早期,抽屉可以正常工作 - 正确打开和关闭。由于已经进行了几处更改(没有直接针对抽屉或其支架),抽屉不再使用 Navigator.of(context).pop() 和 Navigator.pop(context) 关闭。

            我进行了更多挖掘,发现您可以使用 Scaffold.of(context).openEndDrawer 来关闭抽屉,而不是使用 Navigator.pop - 即使它看起来不应该这样做。直到现在我从未使用过这个功能,但它工作得很好。希望这对遇到同样问题的人有所帮助。

            【讨论】:

            • Scaffold.of(context).openEndDrawer 将打开末端抽屉,因此在打开末端抽屉时,它可能会关闭当前抽屉,它会完成您的工作,但这不是正确的方法,
            【解决方案9】:

            您可以根据需要使用以下代码。

            当你想删除并推送新路由时:

            Navigator.of(context).popAndPushNamed('/routeName');
            

            当你只想弹出时:

            Navigator.of(context).pop();
            

            【讨论】:

              【解决方案10】:

              其实很简单

              问题说明:在默认主页中,当有人按下返回按钮时,(如果抽屉打开)它会关闭,否则会提示退出应用程序“是”和“否”。

              解决方案

              1. 添加

                GlobalKey _scaffoldKey = new GlobalKey();

              2. Make Function Future _onWillPop() async 处理所需的问题陈述

              3. 如下源代码中给出的调用键和 onWillPop

              通过完整的源代码查看源代码中与此问题陈述相关的添加

              import 'package:flutter/material.dart';
              
              class HomePage extends StatefulWidget {
                @override
                _HomePageState createState() => _HomePageState();
              }
              
              class _HomePageState extends State<HomePage> {
                GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
              
                Future<bool> _onWillPop() async {
                  if(_scaffoldKey.currentState != null && _scaffoldKey.currentState!.isDrawerOpen){
                    return true;
                  }
                  return (await showDialog(
                        context: context,
                        builder: (context) => new AlertDialog(
                          title: new Text('Leaving our App?'),
                          content: new Text('Are you sure you want to Exit?'),
                          actions: <Widget>[
                            TextButton(
                              onPressed: () => Navigator.of(context).pop(false),
                              child: new Text('No'),
                            ),
                            TextButton(
                              onPressed: () => Navigator.of(context).pop(true),
                              child: new Text('Yes'),
                            ),
                          ],
                        ),
                      )) ??
                      false;
                }
              
                @override
                Widget build(BuildContext context) {
                  return Scaffold(
                    key: _scaffoldKey,
                    body: WillPopScope(
                      onWillPop: _onWillPop,
                      child: Container(
                        child: Center(
                          child: Text("Welcome My App"),
                        ),
                      ),
                    ),
                    drawer: SideDrawer(),
                  );
                }
              }
              

              【讨论】:

                【解决方案11】:

                Navigate.of(context).pop();
                导航.pop(contex);

                必须是 onTap() 函数中的第一个

                例如:

                 onTap: () {
                 Navigator.of(context).pop();//before pushing to any other route 
                 Navigator.push(
                 context,
                 MaterialPageRoute(
                 builder: (BuildContext context) => Screen2(),
                   ),
                  );
                 }
                

                【讨论】:

                • 欢迎来到 Stack Overflow,感谢您的回答。但是,这确实是重复的,因为接受的答案已经是使用 Navigator.pop()。感觉就像您正在尝试回答一些说这对他们不起作用的评论者,当您拥有该特权时,最好在评论中这样做。
                猜你喜欢
                • 2020-12-26
                • 1970-01-01
                • 2021-10-22
                • 2014-04-02
                • 1970-01-01
                • 2015-02-13
                • 2020-09-13
                • 1970-01-01
                相关资源
                最近更新 更多