Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter: How to open Drawer programmatically

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

like image 667
krishnaji Avatar asked Sep 01 '19 17:09

krishnaji


People also ask

How do you open the drawer on a button click in Flutter?

If you create an Scafold there is an option for drawer. If you now create this drawer you get automaticly the menu icon on the leading position of the appbar.

How do you open the drawer from another class in Flutter?

Make a component out of your drawer and put your new page (or the page you want to open your drawer in) in it's own scaffold (and not a component by itself) then import your drawer and insert it in the scaffold drawer. =)

How do you open the navigation drawer from the right side in Flutter?

To open navigation drawer from right side with Dart Null Safety, You should use endDrawer(). There is two drawer arguments available in flutter. endDrawer (Right side) you can see the example for endDrawer.

How to close a drawer in flutter?

After a user taps an item, you might want to close the drawer. You can do this by using the Navigator. When a user opens the drawer, Flutter adds the drawer to the navigation stack. Therefore, to close the drawer, call Navigator.pop (context).

How do I programmatically open a drawer?

To open the drawer programmatically using Scaffold.of (context) you'll have to ensure (thanks Krolaw !) that the context inside which the call is made is aware of the Scaffold. A clean way to do it is to wrap the button in a builder. I've edited the answer to include a minimal full working example.

How to create a material design drawer header in flutter?

To add a basic navigation drawer in Flutter, you must first use MaterialApp in your project. Then, the Drawer widget can be added to the Scaffold widget. Inside the Scaffold, add the Drawer property and assign the Drawer widget Inside the ListView, add the DrawerHeader widget. This will create a material design drawer header

How to disable the slide to open functionality of a drawer?

To disable the slide to open functionality you can set the property drawerEnableOpenDragGesture on Scaffold to false. To open the drawer programmatically using Scaffold.of (context) you'll have to ensure (thanks Krolaw !) that the context inside which the call is made is aware of the Scaffold.


2 Answers

Null safe code

  • Using GlobalKey:

    final GlobalKey<ScaffoldState> _key = GlobalKey(); // Create a key  @override Widget build(BuildContext context) {   return Scaffold(     key: _key, // Assign the key to Scaffold.     drawer: Drawer(),     floatingActionButton: FloatingActionButton(       onPressed: () => _key.currentState!.openDrawer(), // <-- Opens drawer     ),   ); } 
  • Using Builder:

    @override Widget build(BuildContext context) {   return Scaffold(     drawer: Drawer(),     floatingActionButton: Builder(builder: (context) {       return FloatingActionButton(         onPressed: () => Scaffold.of(context).openDrawer(), // <-- Opens drawer.       );     }),   ); } 

If you want to disable opening the Drawer using a drag gesture, you can set

Scaffold(   drawerEnableOpenDragGesture: false   // above code ... ) 
like image 104
CopsOnRoad Avatar answered Sep 20 '22 15:09

CopsOnRoad


  1. To disable the slide to open functionality you can set the property drawerEnableOpenDragGesture on Scaffold to false.
 import 'package:flutter/material.dart';  void main() {   runApp(MyApp()); }  class MyApp extends StatelessWidget {   // This widget is the root of your application.   @override   Widget build(BuildContext context) {     return MaterialApp(       home: Scaffold(         // this to prevent the default sliding behaviour         drawerEnableOpenDragGesture: false,         drawer: Drawer(),         appBar: AppBar(           leading: Builder(builder: (context) => // Ensure Scaffold is in context             IconButton(               icon: Icon(Icons.menu),               onPressed: () => Scaffold.of(context).openDrawer()             ),           ),         )       )     );   } }  
  1. To open the drawer programmatically using Scaffold.of(context) you'll have to ensure (thanks Krolaw !) that the context inside which the call is made is aware of the Scaffold.

    A clean way to do it is to wrap the button in a builder. I've edited the answer to include a minimal full working example.

    Scaffold is a widget that implements material design principles, so be aware that to be able to call this method, you'll need to import 'package:flutter/material.dart'; and your widget needs to have a MaterialApp as ancestor.

Codepen demo


As with many Flutter things, there are other solutions to ensure Scaffold is in context.

Error messages are IMO among the best features of flutter framework, allow me to humbly suggest to always read them thoroughly and to explore the documentation they point at.

For instance, this is part of the error message that one gets if calling openDrawer outside of a proper context:

Scaffold.of() called with a context that does not contain a Scaffold.

No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This usually happens when the context provided is from the same StatefulWidget as that whose build function actually creates the Scaffold widget being sought.

There are several ways to avoid this problem. The simplest is to use a Builder to get a context that is "under" the Scaffold. For an example of this, please see the documentation for Scaffold.of(): https://api.flutter.dev/flutter/material/Scaffold/of.html

A more efficient solution is to split your build function into several widgets. This introduces a new context from which you can obtain the Scaffold. In this solution, you would have an outer widget that creates the Scaffold populated by instances of your new inner widgets, and then in these inner widgets you would use Scaffold.of().

A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function.

like image 39
giulp Avatar answered Sep 17 '22 15:09

giulp