Flutter:如何以编程方式打开抽屉

时间:2019-09-01 17:37:38

标签: flutter dart flutter-layout

我想以编程方式而不是通过滑动来打开Drawer,如何禁用该滑动功能(抽屉的触摸功能)

6 个答案:

答案 0 :(得分:6)

更新

最初,您发布了有关防止Drawer在点击时打开的问题。因此,此解决方案适用于您的原始帖子。

输出:

enter image description here

Drawer只能通过滑动而不是通过点击图标来打开。

您需要创建一个GlobalKey并在其上使用openDrawer()方法。

GlobalKey<ScaffoldState> _drawerKey = GlobalKey();
bool enabled = false; // tracks if drawer should be opened or not

@override
Widget build(BuildContext context) {
  testing();
  return Scaffold(
    key: _drawerKey, // assign key to Scaffold
    drawer: Drawer(),
    appBar: AppBar(
      leading: IconButton(
        icon: Icon(Icons.menu),
        onPressed: () {
          if (enabled) {
            // open drawer if this value is true
            _drawerKey.currentState.openDrawer();
          }
        },
      ),
    ),
  );
}

只要您需要打开抽屉,只需使用

_drawerKey.currentState.openDrawer();

答案 1 :(得分:6)

这是另一个通过汉堡图标以编程方式打开抽屉且没有应用栏的示例:-

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  var scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        key: scaffoldKey,
        drawer: new Drawer(
          child: new ListView(
            padding: EdgeInsets.zero,
            children: <Widget>[
              DrawerHeader(
                child: Text('Drawer Header'),
                decoration: BoxDecoration(
                  color: Colors.blue,
                ),
              ),
              ListTile(
                title: Text('Item 1'),
                onTap: () {
                  //Do some stuff here
                  //Closing programmatically - very less practical use
                  scaffoldKey.currentState.openEndDrawer();
                },
              )
            ],
          ),
        ),
        body: Stack(
          children: <Widget>[
            new Center(
                child: new Column(
              children: <Widget>[],
            )),
            Positioned(
              left: 10,
              top: 20,
              child: IconButton(
                icon: Icon(Icons.menu),
                onPressed: () => scaffoldKey.currentState.openDrawer(),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

答案 2 :(得分:2)

很麻烦,但是可以。要禁用幻灯片以打开功能,可以将脚手架上的属性drawerEdgeDragWidth设置为0。

@override
Widget build(BuildContext context) {
  return Scaffold(
    drawerEdgeDragWidth: 0, // THIS WAY IT WILL NOT OPEN
    drawer: Drawer(),
    appBar: AppBar(
      leading: IconButton(
        icon: Icon(Icons.menu),
        onPressed: () {
          Scaffold.of(context).openDrawer();
        },
      ),
    ),
  );
}

答案 3 :(得分:1)

调用Scaffold.of无效,因为上下文不包含Scaffold。上面的一些解决方案忽略了这一点,其他的则使用了GlobalKey。我相信最干净的解决方案是将按钮包装在Builder中:

Scaffold(
   drawerEnableOpenDragGesture: false, // Prevent user sliding open
   appBar: AppBar(
      automaticallyImplyLeading: false,
      title: Text("Some Title"),
      actions: [
         Builder(builder: (context) => // Ensure Scaffold is in context
            IconButton(
               icon: Icon(Icons.settings),
               onPressed: () => Scaffold.of(context).openDrawer()
         )),
      ],
   ),
   // TODO ...
)

答案 4 :(得分:0)

appBar: AppBar(

      automaticallyImplyLeading: false,
      title: Text(
        "Infilon Technologies",
        style:
            TextStyle(fontFamily: "Poppins", fontWeight: FontWeight.w600),
      ),
      actions: <Widget>[
        IconButton(
          icon: Icon(Icons.menu),
          onPressed: () {
            if (_scaffoldKey.currentState.isEndDrawerOpen) {
              _scaffoldKey.currentState.openDrawer();
            } else {
              _scaffoldKey.currentState.openEndDrawer();
            }
          },
        ),
      ],
    ),

答案 5 :(得分:0)

您必须将小部件包装在新的BuildContext中,因为您使用的上下文很可能是外部上下文,并且不了解Scaffold。

drawer: Builder(
  builder: (BuildContext internalContext) {
    return _drawer(internalContext);
  },
),

查看完整代码

class SampleAppPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: _appBar(context),
        drawer: new Builder(
          builder: (BuildContext internalContext) {
            return _drawer(internalContext);
          },
        ),
        body: new Builder(
          builder: (BuildContext internalContext) {
            return _body(internalContext);
          },
        ),
      ),
    );
  }

  Widget _appBar(BuildContext context) {
    return new AppBar(
      title: new Text('Drawer example'),
    );
  }

  Widget _drawer(BuildContext context) {
    return new Center(
      child: new RaisedButton(
        child: new Text('Close drawer'),
        onPressed: () => Navigator.of(context).pop(),
      ),
    );
  }

  Widget _body(BuildContext context) {
    return new Column(
      children: <Widget>[
        new RaisedButton(
          child: new Text('Open via Scaffold context'),
          onPressed: () => Scaffold.of(context).openDrawer(),
        ),
      ],
    );
  }
}