Flutter: How to open Drawer programmatically

前端 未结 6 980
暖寄归人
暖寄归人 2020-12-29 21:11

I want to open Drawer programmatically not by sliding it, how to disable that sliding functionality (touch functionality of Drawer)

相关标签:
6条回答
  • 2020-12-29 21:44

    To disable the slide to open functionality you can set the property endDrawerEnableOpenDragGesture on Scaffold to false.

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        endDrawerEnableOpenDragGesture: false, // THIS WAY IT WILL NOT OPEN
        drawer: Drawer(),
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.menu),
            onPressed: () {
              Scaffold.of(context).openDrawer();
            },
          ),
        ),
      );
    }
    
    0 讨论(0)
  • 2020-12-29 21:47

    Here is another example of opening the drawer programmatically from a hamburger icon and without the Appbar:-

    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(),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-29 21:50

    Calling Scaffold.of doesn't work because the context doesn't contain the Scaffold. Some solutions above have ignored this, others have used GlobalKey. I believe the cleanest solution is wrapping the button in a 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 ...
    )
    
    0 讨论(0)
  • 2020-12-29 21:51

    You have to wrap your widgets in a new BuildContext, because most likely, the context you are using is an outer context, and is not aware of the Scaffold.

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

    Check out the full code

    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(),
            ),
          ],
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-29 21:59
    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();
                }
              },
            ),
          ],
        ),
    
    0 讨论(0)
  • 2020-12-29 22:07

    You'll need to create a GlobalKey and use openDrawer() method on it.

    GlobalKey<ScaffoldState> _drawerKey = GlobalKey();
    
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        key: _drawerKey, // assign key to Scaffold
        drawer: Drawer(),
        floatingActionButton: FloatingActionButton(
          onPressed: () => _drawerKey.currentState.openDrawer(), // open drawer
        ),
      );
    }
    
    0 讨论(0)
提交回复
热议问题