在 Flutter 中按下后退按钮关闭导航抽屉

问题描述 投票:0回答:3

我的第一个 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 csedu
3个回答
17
投票

您可以复制粘贴运行下面的完整代码
步骤一:你需要脚手架钥匙来控制抽屉,所以你需要

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

步骤 2:在
onWillPop
中,您可以检查
isDrawerOpen
并执行
Navigator.pop

代码片段

 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(

工作演示

enter image description here

完整代码

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);
  }
}

0
投票

由于我的主屏幕,我的后退按钮在抽屉上不起作用。从抽屉中删除 WillPopScope 并将以下代码放入主屏幕中。

WillPopScope(
  onWillPop: () async {
    return Navigator.of(context).canPop();
  },
  child: Scaffold(

-1
投票

只需添加 Navigator.pop(context);

ListTile(
  title: const Text('Item 1'),
  onTap: () {
    // Update the state of the app
    // ...
    // Then close the drawer
    Navigator.pop(context);
  },
),
© www.soinside.com 2019 - 2024. All rights reserved.