I want to open Drawer
programmatically not by sliding it, how to disable that sliding functionality (touch functionality of Drawer)
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();
},
),
),
);
}
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(),
),
),
],
),
),
);
}
}
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 ...
)
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(),
),
],
);
}
}
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();
}
},
),
],
),
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
),
);
}