How to Persist Drawer Through App In Flutter?
The drawer is one type of ListView Widget which is used for switch pages in the application as a user will select an option. So in this article, we will go through How to Persist Drawer Through App In Flutter?
How to Persist Drawer Through App In Flutter?
To Persist Drawer Through App follow the steps as below:
- Create a class for your drawer
Your widget should be its own stateful or stateless widget. This way, you just have to instantiate it each time.
class MyDrawer extends StatelessWidget { @override Widget build(BuildContext context) { return Drawer(...); } }
And then when using it on each page:
Scaffold( drawer: MyDrawer(...), ... )
- Create a class for your scaffold
If having to include the same drawer in a scaffold for each page is still too much code, you can instead use a class that encapsulates your scaffold. It would essentially take inputs for each of the scaffold inputs you actually use.
class MyScaffold extends StatelessWidget { final Widget body; MyScaffold({this.body}); @override Widget build(BuildContext context) { return Scaffold( body: body, drawer: MyDrawer(...), ); } }
- To share a drawer between all pages we could add a builder in our MaterialApp instance. This will instantiate a Scaffold under Navigator but above all routes.
MaterialApp( title: 'Flutter Demo', builder: (context, child) { return Scaffold( drawer: MyDrawer(), body: child, ); }, home: MyHome() )
Inside your page, you can instantiate another Scaffold without restriction as you’d usually do.
You can then show the shared drawer by doing the following in any widget under MaterialApp :
final ScaffoldState scaffoldState = context.rootAncestorStateOfType(TypeMatcher<ScaffoldState>()); scaffoldState.openDrawer();
class RootScaffold { static openDrawer(BuildContext context) { final ScaffoldState scaffoldState = context.rootAncestorStateOfType(TypeMatcher<ScaffoldState>()); scaffoldState.openDrawer(); } }
- Navigation Drawer with Multiple Fragments using bloc package
First, add below dependencies in your pubspec.yaml file
flutter_bloc: ^4.0.0
Now create the below files.
drawer_event.dart
import 'nav_drawer_state.dart'; abstract class NavDrawerEvent { const NavDrawerEvent(); } class NavigateTo extends NavDrawerEvent { final NavItem destination; const NavigateTo(this.destination); }
nav_drawer_bloc.dart
import 'package:bloc/bloc.dart'; import 'drawer_event.dart'; import 'nav_drawer_state.dart'; class NavDrawerBloc extends Bloc<NavDrawerEvent, NavDrawerState> { @override NavDrawerState get initialState => NavDrawerState(NavItem.homePage); @override Stream<NavDrawerState> mapEventToState(NavDrawerEvent event) async* { if (event is NavigateTo) { if (event.destination != state.selectedItem) { yield NavDrawerState(event.destination); } } } }
nav_drawer_state.dart
class NavDrawerState { final NavItem selectedItem; const NavDrawerState(this.selectedItem); } enum NavItem { homePage, profilePage, orderPage, myCart, }
Now it’s time to create an actual drawer like the below:
import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutterdrawerwithbloc/bloc/drawer_event.dart'; import 'package:flutterdrawerwithbloc/bloc/nav_drawer_bloc.dart'; import 'package:flutterdrawerwithbloc/bloc/nav_drawer_state.dart'; class NavDrawerWidget extends StatelessWidget { final String accountName; final String accountEmail; final List<_NavigationItem> _listItems = [ _NavigationItem(true, null, null, null), _NavigationItem(false, NavItem.homePage, "Home", Icons.home), _NavigationItem(false, NavItem.profilePage, "Profile Page", Icons.person), _NavigationItem(false, NavItem.orderPage, "My Orders", Icons.list), _NavigationItem(false, NavItem.myCart, "My Cart", Icons.shopping_cart), ]; NavDrawerWidget(this.accountName, this.accountEmail); @override Widget build(BuildContext context) => Drawer( child: Container( child: ListView.builder( padding: EdgeInsets.zero, itemCount: _listItems.length, itemBuilder: (BuildContext context, int index) => BlocBuilder<NavDrawerBloc, NavDrawerState>( builder: (BuildContext context, NavDrawerState state) => _buildItem(_listItems[index], state), )), )); Widget _buildItem(_NavigationItem data, NavDrawerState state) => data.header ? _makeHeaderItem() : _makeListItem(data, state); Widget _makeHeaderItem() => UserAccountsDrawerHeader( accountName: Text(accountName, style: TextStyle(color: Colors.white)), accountEmail: Text(accountEmail, style: TextStyle(color: Colors.white)), decoration: BoxDecoration(color: Colors.indigo), currentAccountPicture: CircleAvatar( backgroundColor: Colors.white, foregroundColor: Colors.amber, child: Icon( Icons.person, size: 54, ), ), ); Widget _makeListItem(_NavigationItem data, NavDrawerState state) => Card( shape: ContinuousRectangleBorder(borderRadius: BorderRadius.zero), borderOnForeground: true, elevation: 0, margin: EdgeInsets.zero, child: Builder( builder: (BuildContext context) => ListTile( title: Text( data.title, style: TextStyle( color: data.item == state.selectedItem ? Colors.green : Colors.blueGrey, ), ), leading: Icon( data.icon, color: data.item == state.selectedItem ? Colors.green : Colors.blueGrey, ), onTap: () => _handleItemClick(context, data.item), ), ), ); void _handleItemClick(BuildContext context, NavItem item) { BlocProvider.of<NavDrawerBloc>(context).add(NavigateTo(item)); Navigator.pop(context); } } class _NavigationItem { final bool header; final NavItem item; final String title; final IconData icon; _NavigationItem(this.header, this.item, this.title, this.icon); }
Main.dart will look like below:
import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutterdrawerwithbloc/bloc/nav_drawer_bloc.dart'; import 'package:flutterdrawerwithbloc/bloc/nav_drawer_state.dart'; import 'package:flutterdrawerwithbloc/drawer_widget.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Navigation Drawer Demo', theme: ThemeData(primarySwatch: Colors.blue, scaffoldBackgroundColor: Colors.white), home: MyHomePage(), ); ; } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { NavDrawerBloc _bloc; Widget _content; @override void initState() { super.initState(); _bloc = NavDrawerBloc(); _content = _getContentForState(_bloc.state.selectedItem); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) => BlocProvider<NavDrawerBloc>( create: (BuildContext context) => _bloc, child: BlocListener<NavDrawerBloc, NavDrawerState>( listener: (BuildContext context, NavDrawerState state) { setState(() { _content = _getContentForState(state.selectedItem); }); }, child: BlocBuilder<NavDrawerBloc, NavDrawerState>( builder: (BuildContext context, NavDrawerState state) => Scaffold( drawer: NavDrawerWidget("AskNilesh", "[email protected]"), appBar: AppBar( title: Text(_getAppbarTitle(state.selectedItem)), centerTitle: false, brightness: Brightness.light, backgroundColor: Colors.indigo, ), body: AnimatedSwitcher( switchInCurve: Curves.easeInExpo, switchOutCurve: Curves.easeOutExpo,
Conclusion:
In this article, we have learned about How to Persist Drawer Through App In Flutter?
Thanks for Reading!!!
Keep Learning.
Do let us know if you need any assistance with Flutter Development?
FlutterAgency.com is our portal Platform dedicated to Flutter Technology and Flutter Developers. The portal is full of cool resources from Flutter like Flutter Widget Guide, Flutter Projects, Code libs and etc.
FlutterAgency.com is one of the most popular online portal dedicated to Flutter Technology and daily thousands of unique visitors come to this portal to enhance their knowledge on Flutter.
Contemporary ventures
Recent blog
ready to get started?
Fill out the form below and we will be in touch soon!
"*" indicates required fields