【问题标题】:Close Navigation Drawer on Back Button Pressed in Flutter在 Flutter 中按下后退按钮时关闭导航抽屉
【发布时间】:2020-06-04 10:30:03
【问题描述】:

在我的第一个 Flutter 应用中,我有一个材质设计的导航抽屉。这项工作很好,但如果使用WillPopScope 显示AlertDialog 时打开,我没有找到任何方法来关闭后退按钮上的导航抽屉。该应用程序只显示AlertDialog,而不是在后按时关闭抽屉。如果抽屉已经打开,我希望抽屉应该关闭,否则显示AlertDialog

@override
Widget build(BuildContext context) {
  return WillPopScope(
    onWillPop: onBackPressed,
    child: Scaffold(
      appBar: AppBar(
        title: Text("Home"),
      ),
      drawer: Drawer(
      ),
      body: Center(
        child: Text("Home"),
      ),
    ),
  );
}

onBackPressed 显示关闭应用程序的对话框。

Future<bool> onBackPressed() {
  return showDialog(
      barrierDismissible: false,
      context: context,
      builder: (context) => AlertDialog(
            title: Text("Do you want to exit?"),
            actions: <Widget>[
              FlatButton(
                  onPressed: () => Navigator.pop(context, false),
                  child: Text("No")),
              FlatButton(
                  onPressed: () => Navigator.pop(context, true),
                  child: Text("Yes"))
            ],
          ));
}

谁能指导我如何做到这一点?

【问题讨论】:

  • 我复制/粘贴你的代码,它工作正常。当我按下后退按钮时,它会关闭抽屉

标签: android flutter dart material-design


【解决方案1】:

只需添加 Navigator.pop(context);

ListTile(
  title: const Text('Item 1'),
  onTap: () {
    // Update the state of the app
    // ...
    // Then close the drawer
    Navigator.pop(context);
  },
),

【讨论】:

    【解决方案2】:

    您可以在下面复制粘贴运行完整代码
    第 1 步:您需要 Scaffold 键来控制抽屉,所以您需要 GlobalKey&lt;ScaffoldState&gt; _key = new GlobalKey&lt;ScaffoldState&gt;();
    第 2 步:在 onWillPop 中,您可以检查 isDrawerOpen 并执行 Navigator.pop

    代码sn-p

     GlobalKey<ScaffoldState> _key = new GlobalKey<ScaffoldState>();
    
      MyHomePage({Key key, this.title}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return WillPopScope(
          onWillPop: () async {
            if (_key.currentState.isDrawerOpen) {
              Navigator.of(context).pop();
              return false;
            }
            return true;
          },
          child: Scaffold(
    

    工作演示

    完整代码

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return WillPopScope(
          onWillPop: () async {
            print("My App Page");
            //return false;
          },
          child: MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: MyHomePage(title: "test",),
          ),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      final String title;
      GlobalKey<ScaffoldState> _key = new GlobalKey<ScaffoldState>();
    
      MyHomePage({Key key, this.title}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return WillPopScope(
          onWillPop: () async {
            if (_key.currentState.isDrawerOpen) {
              Navigator.of(context).pop();
              return false;
            }
            return true;
          },
          child: Scaffold(
            key: _key,
            appBar: AppBar(title: Text(title)),
            body: Center(child: Text('My Page!')),
            drawer: Drawer(
              child: ListView(
                padding: EdgeInsets.zero,
                children: <Widget>[
                  DrawerHeader(
                    child: Text('Drawer Header'),
                    decoration: BoxDecoration(
                      color: Colors.blue,
                    ),
                  ),
                  ListTile(
                    title: Text('page 2'),
                    onTap: () {
                      Navigator.push(
                          context, new MaterialPageRoute(builder: (context) => Page2()));
                    },
                  ),
                  ListTile(
                    title: Text('Item 2'),
                    onTap: () {
                      // Update the state of the app
                      // ...
                      // Then close the drawer
                      Navigator.pop(context);
                    },
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    
    
    class Page2 extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return WillPopScope(
          onWillPop: () async {
            print("Page2");
            _popNavigationWithResult(context, 'from_back');
            return false;
          },
          child: Scaffold(
            floatingActionButton: FloatingActionButton(
              onPressed: () {
                _popNavigationWithResult(context, 'from_button');
              },
            ),
            body: Container(
              child: Center(
                child: Text('Page 2',
                    style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold)),
              ),
            ),
          ),
        );
      }
    
      void _popNavigationWithResult(BuildContext context, dynamic result) {
        Navigator.pop(context, result);
      }
    }
    

    【讨论】:

    • 您能否详细说明,而不仅仅是代码,并指导我如何将它与AlertDialog 一起使用,正如我所问的那样?谢谢
    • 您的意思是当单击设备返回按钮时,显示 AlertDialog 以询问用户是否要关闭抽屉?或直接关闭抽屉并显示 AlertDialog 询问用户是否要离开?
    • 不,如果抽屉是打开的,那么它应该在后按时关闭并且不显示对话框。否则对话框显示
    • 你看到我发布的动画 gif 了吗?你能刷新你的页面吗?
    猜你喜欢
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-06
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    • 2020-12-20
    相关资源
    最近更新 更多