Skip to main content

Flutter & Dart VSCode: Creating Custom Material Drawer using InkWell for Android

In this exapmle, we will learn how to add customize material drawer with some cool UI look as well as some ripple effect just like below:
 
Couple of things we should have on our machine prior to implement this functionality:
Now, Follow the below steps:
  • Once you have your project created, then you will notice in the project structure we have 'Main.Dart' file.Go to 'Main.Dart' file and add below class and name it 
    CustomListTile
  1. class CustomListTile extends StatelessWidget{  
  2.   
  3.   final IconData icon;  
  4.   final  String text;  
  5.   final Function onTap;  
  6.   
  7.   CustomListTile(this.icon, this.text, this.onTap);  
  8.   @override  
  9.   Widget build(BuildContext context){  
  10.     //ToDO   
  11.     return Padding(  
  12.       padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),  
  13.       child:Container(  
  14.         decoration: BoxDecoration(  
  15.           border: Border(bottom: BorderSide(color: Colors.grey.shade400))  
  16.         ),  
  17.       child: InkWell(  
  18.         splashColor: Colors.orangeAccent,  
  19.         onTap: onTap,  
  20.         child: Container(  
  21.           height: 40,  
  22.           child: Row(  
  23.             mainAxisAlignment : MainAxisAlignment.spaceBetween,  
  24.             children: <Widget>[  
  25.             Row(children: <Widget>[  
  26.             Icon(icon),  
  27.             Padding(  
  28.               padding: const EdgeInsets.all(8.0),  
  29.             ),  
  30.             Text(text, style: TextStyle(  
  31.               fontSize: 16  
  32.             ),),  
  33.           ],),  
  34.         Icon(Icons.arrow_right)  
  35.       ],)  
  36.         )   
  37.     ),  
  38.     ),  
  39.     );  
  40.   }  
  41. }  
  • Lets talk about CustomListTile class, which we have just implemented. we have inherited this class from StateLessWidget which is a class of widget that does not require mutable state. A stateless widget is a widget that describes part of the user interface by building a constellation of other widgets that describe the user interface more concretely. The building process continues recursively until the description of the user interface is fully concrete (e.g., consists entirely of RenderObjectWidgets, which describe concrete RenderObjects). to make it more generic, we have three objects(Icon Type, Text, Action for onTap()) and one constructor which takes these as parameter which we are using while calling this class object. Like we did it below: 
    1.            CustomListTile(Icons.person, 'Profile', ()=>{}),    
    2.            CustomListTile(Icons.notifications, 'Notification', ()=>{}),    
    3.            CustomListTile(Icons.settings, 'Settings', ()=>{}),    
    4.            CustomListTile(Icons.lock'Log Out', ()=>{}),   
  • More in this class you have below implementation of InkWell class which is a rectangular area of a Material that responds to touch. For a variant of this widget that does not clip splashes.The highlight is a rectangle the size of the box. The InkWell widget must have a Material widget as an ancestor. The Material widget is where the ink reactions are actually painted. This matches the material design premise wherein the Material is what is actually reacting to touches by spreading ink. Just Like below
    1. child: InkWell(      
    2.        splashColor: Colors.orangeAccent,      
    3.        onTap: onTap,      
    4.        child: Container(      
    5.          height: 40,      
    6.          child: Row(      
    7.            mainAxisAlignment : MainAxisAlignment.spaceBetween,      
    8.            children: <Widget>[      
    9.            Row(children: <Widget>[      
    10.            Icon(icon),      
    11.            Padding(      
    12.              padding: const EdgeInsets.all(8.0),      
    13.            ),      
    14.            Text(text, style: TextStyle(      
    15.              fontSize: 16      
    16.            ),),      
    17.          ],),      
    18.        Icon(Icons.arrow_right)      
    19.      ],)      
    20.        )     
  • Edit build method and paste below code:
  1. @override  
  2.   Widget build(BuildContext context) {  
  3.     // This method is rerun every time setState is called, for instance as done  
  4.     // by the _incrementCounter method above.  
  5.     //  
  6.     // The Flutter framework has been optimized to make rerunning build methods  
  7.     // fast, so that you can just rebuild anything that needs updating rather  
  8.     // than having to individually change instances of widgets.  
  9.     return Scaffold(  
  10.       appBar: AppBar(  
  11.         // Here we take the value from the MyHomePage object that was created by  
  12.         // the App.build method, and use it to set our appbar title.  
  13.         title: Text(widget.title),  
  14.       ),  
  15.       drawer: Drawer(  
  16.         // Add a ListView to the drawer. This ensures the user can scroll  
  17.         // through the options in the drawer if there isn't enough vertical  
  18.         // space to fit everything.  
  19.         child: ListView(  
  20.           children: <Widget>[  
  21.             DrawerHeader(  
  22.               decoration: BoxDecoration(  
  23.                 gradient: LinearGradient(colors: <Color>[  
  24.                   Colors.lightBlue,  
  25.                   Colors.blue  
  26.                 ])  
  27.               ),  
  28.               child: Container(  
  29.                 child: Column(  
  30.                   children: <Widget>[  
  31.                     Material(  
  32.                       borderRadius: BorderRadius.all(Radius.circular(50.0)),  
  33.                       elevation: 10,  
  34.                       child: Padding(padding: EdgeInsets.all(8.0),  
  35.                       child: Image.asset("assets/images/drawerHeader.png", height: 90, width: 90),  
  36.                       ),  
  37.                     ),  
  38.                     Text('Flutter', style: TextStyle(color: Colors.white, fontSize: 25.0),)  
  39.                   ],  
  40.                 ),  
  41.               )),  
  42.             CustomListTile(Icons.person, 'Profile', ()=>{}),  
  43.             CustomListTile(Icons.notifications, 'Notification', ()=>{}),  
  44.             CustomListTile(Icons.settings, 'Settings', ()=>{}),  
  45.             CustomListTile(Icons.lock'Log Out', ()=>{}),  
  46.           ],  
  47.   
  48.         ),  
  49.       ),  
  50.       body: Center(  
  51.         // Center is a layout widget. It takes a single child and positions it  
  52.         // in the middle of the parent.  
  53.         child: Column(  
  54.           // Column is also layout widget. It takes a list of children and  
  55.           // arranges them vertically. By default, it sizes itself to fit its  
  56.           // children horizontally, and tries to be as tall as its parent.  
  57.           //  
  58.           // Invoke "debug painting" (press "p" in the console, choose the  
  59.           // "Toggle Debug Paint" action from the Flutter Inspector in Android  
  60.           // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)  
  61.           // to see the wireframe for each widget.  
  62.           //  
  63.           // Column has various properties to control how it sizes itself and  
  64.           // how it positions its children. Here we use mainAxisAlignment to  
  65.           // center the children vertically; the main axis here is the vertical  
  66.           // axis because Columns are vertical (the cross axis would be  
  67.           // horizontal).  
  68.           mainAxisAlignment: MainAxisAlignment.center,  
  69.           children: <Widget>[  
  70.             Text(  
  71.               'You have pushed the button this many times:',  
  72.             ),  
  73.             Text(  
  74.               '$_counter',  
  75.               style: Theme.of(context).textTheme.display1,  
  76.             ),  
  77.           ],  
  78.         ),  
  79.       ),  
  80.       floatingActionButton: FloatingActionButton(  
  81.         onPressed: _incrementCounter,  
  82.         tooltip: 'Increment',  
  83.         child: Icon(Icons.add),  
  84.       ), // This trailing comma makes auto-formatting nicer for build methods.  
  85.     );  
  86.   }  
  87. }  
  • In the above code we have added one child container inside out ListView, which has our code for having image in DrawerHeader just like below:
    1. child: Container(    
    2.                 child: Column(    
    3.                   children: <Widget>[    
    4.                     Material(    
    5.                       borderRadius: BorderRadius.all(Radius.circular(50.0)),    
    6.                       elevation: 10,    
    7.                       child: Padding(padding: EdgeInsets.all(8.0),    
    8.                       child: Image.asset("assets/images/drawerHeader.png", height: 90, width: 90),    
    9.                       ),    
    10.                     ),    
    11.                     Text('Flutter', style: TextStyle(color: Colors.white, fontSize: 25.0),)    
    12.                   ],    
    13.                 ),    
    14.               )),   
  • I have used borderRadius to make the image rounded and elevation is the shadow effect of the image. You can play around with these to observe the changes.
  • Create a folder in the root directory, name it 'assets' and create another folder inside it, name it 'images'. It should look like below folder stucture and paste one image which you want to add in the header section of drawer. Mind the name of the file.
  • Every pub package needs some metadata so it can specify its dependencies. Pub packages that are shared with others also need to provide some other information so users can discover them. All of this metadata goes in the package’s pubspec: a file named pubspec.yaml that’s written in the YAML language.Go to root directory and find file 'pubspec.yaml'.
  • Supported fields
    A pubspec can have the following fields:
    name
    Required for every package.
    version
    Required for packages that are hosted on the Pub site.
    description
    Required for packages that are hosted on the Pub site.
    author or authors
    Optional.
    homepage
    Optional. URL pointing to the package’s homepage (or source code repository).
    repository
    Optional. URL pointing to the package’s source code repository.
    issue_tracker
    Optional. URL pointing to an issue tracker for the package.
    documentation
    Optional. URL pointing to documentation for the package.
    dependencies
    Can be omitted if your package has no dependencies.
    dev_dependencies
    Can be omitted if your package has no dev dependencies.
    dependency_overrides
    Can be omitted if you do not need to override any dependencies.
    environment
    Required as of Dart 2.
    executables
    Optional. Used to put a package’s executables on your PATH.
    publish_to
    Optional. Specify where to publish a package.
  • Go to root directory and find file 'pubspec.yaml'.

  • edit the below line and the entry for your assest which is our image in our example. Mind the Tab because it will give exception otherwise:
  1. flutter:  
  2.   # The following line ensures that the Material Icons font is  
  3.   # included with your application, so that you can use the icons in  
  4.   # the material Icons class.  
  5.   uses-material-design: true  
  6.   assets:  
  7.   - assets/images/drawerHeader.png  
  • Now press F5 to run the application and you should have new customize material drawer just like below:
Congratulations!!!
You have done it. feel free to ping me if you face any issue. 

Comments

Popular posts from this blog

Install Flutter & Dart on windows

Things we should have in order to work with Flutter and dart: Visual Studio Code Android Studio So first install these two guys from the link. Something About the Cross Platform Mobile Development: Cross Platform Mobile development refers to one common development platform which can be used for multiple mobile operating system like Android, iOS and Windows. There are number of technologies which support cross platform mobile development and to name a few are like Xamarin, CodeName One, Flutter & Dart, Apache Cordova  etc. I did one review about Xamarin technology because it's been while that I am using Xamarin for Android and iOS. You can read more about it,  Here... Flutter & Dart Flutter is Google’s portable UI toolkit for building beautiful, natively-compiled applications for mobile, web, and desktop from a single codebase. Dart is the language which we use for cross platform mobile development with Flutter.  In this example we ...