Creating Drawer Layout Using Material Design In Xamarin.Android

In this article, you will learn how to create Drawer Layout using Material Design in Xamarin.Android. 

Step 1- Create a Sample project

Open VS > File > Cross-Platform > Blank App (Native Portable).

Xamarin

Step 2- Creating required styles

Xamarin

Open styles and write a custom style below. Just take a look below.

Xamarin

So, to customize, we need to set and create our custom theme (if you want to) in styles.

  1. <style name="MyTheme" parent="Theme.AppCompat.Light.NoActionBar">  
  2.    <item name="windowNoTitle">true</item>  
  3.    <item name="windowActionBar">false</item>  
  4.    <item name="colorPrimary">#16A085</item>  
  5.    <item name="colorPrimaryDark">#1976D2</item>  
  6.    <item name="colorAccent">#FF4081</item>  
  7.    <item name="drawerArrowStyle">@style/MyDrawerArrowStyle</item>  
  8.  </style>  
  9.   
  10.  <style name="MyDrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">  
  11.    <item name="color">#F5F5F5</item>  
  12.    <item name="spinBars">true</item>  
  13.  </style>  

So, I have overriden all values which are required with my custom values.

Step 2 - Creating Drawer Layout

Now, let's add a new layout. Right click >> Add New >> Android Layout >> DrawerLayout.axml.

Xamarin

Now, we need to add the required NuGet packages before we start writing UI. So, download the following NuGet packages.

  • Xamarin.Android.Support.v4 version="25.4.0.2"
  • Xamarin.Android.Support.v7.AppCompat version="25.4.0.2"
  • Xamarin.Android.Support.Fragment version="25.4.0.2"
  • Refractored.Controls.CircleImageView( for circle image view in left drawer)

Now, open DrawerLayout.axml and write the following UI Code.

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     android:orientation="vertical"  
  5.     android:layout_width="fill_parent"  
  6.     android:layout_height="fill_parent">  
  7.   <android.support.v7.widget.Toolbar  
  8.       android:id="@+id/toolbar"  
  9.       android:layout_width="match_parent"  
  10.       android:layout_height="wrap_content"  
  11.       android:minHeight="?attr/actionBarSize"  
  12.       android:background="?attr/colorPrimary"  
  13.       app:theme="@style/MyTheme"  
  14.       app:layout_scrollFlags="scroll|enterAlways"   
  15.       app:popupTheme="@style/ThemeOverlay.AppCompat.Dark" />  
  16.   
  17.   <android.support.v4.widget.DrawerLayout  
  18.       android:id="@+id/drawer_layout"  
  19.       android:layout_width="match_parent"  
  20.       android:layout_height="match_parent">  
  21.     <!-- The Main Content View -->  
  22.     <RelativeLayout  
  23.          android:layout_width="match_parent"  
  24.          android:layout_height="match_parent">  
  25.       <android.support.design.widget.AppBarLayout  
  26.           android:layout_height="wrap_content"  
  27.           android:layout_width="match_parent"  
  28.           android:id="@+id/toolbar_layout">  
  29. <!-- you can create separately and use it here Like this ,but for now i am doing inline for toolbar-->  
  30.         <!--<include  
  31.             layout="@layout/toolbar" />-->  
  32.       </android.support.design.widget.AppBarLayout>  
  33.       <FrameLayout  
  34.           android:id="@+id/content_frame"  
  35.           android:layout_below="@id/toolbar_layout"  
  36.           android:layout_width="match_parent"  
  37.           android:layout_height="match_parent" />  
  38.     </RelativeLayout>  
  39.       
  40.     <!-- The Left Navigation Drawer -->  
  41.       <android.support.design.widget.NavigationView    
  42.       android:id="@+id/nav_view"    
  43.       android:layout_height="match_parent"    
  44.       android:layout_width="240dp"    
  45.       android:layout_gravity="start"  
  46.       app:menu="@layout/left_menu_items"  
  47.       app:headerLayout="@layout/nav_header_main"  
  48.       android:fitsSystemWindows="true" >  
  49.   
  50.     
  51. </android.support.design.widget.NavigationView>  
  52.   </android.support.v4.widget.DrawerLayout>  
  53. </LinearLayout>  

Note

Action Bar is deprecated, so we are using toolbar (which builds a new control on top of ActionBar)

So I referred to my Style for a toolbar like this

app:theme="@style/MyTheme"
 
I am using FrameLayout to replace my Fragment (Reusable UI). The NavigationView represents the below image.

Xamarin

So first, we will create a UI for Header menu. Add a new layout file, say nav_header_main.
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     android:id="@+id/view_container"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="@dimen/nav_header_height"  
  7.     android:gravity="bottom"  
  8.     android:orientation="vertical"  
  9.     android:theme="@style/ThemeOverlay.AppCompat.Dark">  
  10.   <LinearLayout  
  11.       android:layout_width="220dp"  
  12.       android:layout_height="wrap_content"  
  13.       android:layout_centerVertical="true"  
  14.       android:orientation="vertical"  
  15.       android:padding="@dimen/activity_horizontal_margin">  
  16.   
  17.     <refractored.controls.CircleImageView  
  18.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  19.     android:id="@+id/profile_image"  
  20.     android:layout_width="96dp"  
  21.     android:layout_height="96dp"  
  22.     android:src="@drawable/profile"  
  23.     app:civ_border_width="2dp"  
  24.     app:civ_border_color="#D40047"/>  
  25.       
  26.   
  27.     <TextView  
  28.         android:id="@+id/name"  
  29.         android:text="Nina"  
  30.         android:textColor="#1E1E1E"  
  31.         android:layout_width="match_parent"  
  32.         android:layout_height="wrap_content"  
  33.         android:paddingTop="@dimen/nav_header_vertical_spacing"  
  34.         android:textAppearance="@style/TextAppearance.AppCompat.Body1" />  
  35.   
  36.     <TextView  
  37.        android:id="@+id/names"  
  38.        android:layout_below="@id/name"  
  39.        android:text="NinaDibrove@gmail.com"  
  40.        android:textColor="#B0B0B0"  
  41.        android:layout_width="match_parent"  
  42.        android:layout_height="wrap_content"  
  43.        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />  
  44.   
  45.   </LinearLayout>  
  46. </RelativeLayout>  

Put all the images in Drawable folder and refer to it like this. If you're supporting multiple resolutions, put all respective scaled images in remaining Drawable folders. For now, I am adding to drawable only.

Xamarin

android:src="@drawable/profile"

Here, I am setting my profile image which I want to show in Header of Nav. Now, refer this Layout in DrawerLayout.axml like below -

app:headerLayout="@layout/nav_header_main"

Now, we have to create menu items. So, add another layout file and name it as left_menu_items.axml.

  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android">  
  3.   
  4.   <group android:checkableBehavior="single">  
  5.     <item  
  6.         android:id="@+id/nav_home"  
  7.         android:icon="@drawable/ic_Order"  
  8.         android:title="Orders" />  
  9.     <item  
  10.         android:id="@+id/nav_friends"  
  11.         android:icon="@drawable/ic_Redeem"  
  12.         android:title="Redeem" />  
  13.     <item  
  14.         android:id="@+id/nav_profile"  
  15.         android:icon="@drawable/ic_today"  
  16.         android:title="Notifications" />  
  17.   </group>  
  18.   
  19.   <item android:title="Today">  
  20.     <menu>  
  21.       <item  
  22.           android:icon="@drawable/ic_test"  
  23.           android:title="Tasks"  
  24.           android:checkable="true" />  
  25.       <item  
  26.           android:icon="@drawable/ic_forum"  
  27.           android:title="Messages"  
  28.           android:checkable="true" />  
  29.     </menu>  
  30.   </item>  
  31.   
  32. </menu>  

Note

You must place all android:icon images in Drawable folder. 

group android:checkableBehavior="single" means to put a check that only one item can be selected at a time.

Now, refer to this menu in app:menu="@layout/left_menu_items" in DrawerLayout.axml

Step 3 - Creating DrawerLayout Activity file

Xamarin

Open Drawerlayout.cs file and write the code like this -

  1. using System;  
  2.   
  3. using Android.App;  
  4. using Android.Content;  
  5. using Android.Runtime;  
  6. using Android.Views;  
  7. using Android.Widget;  
  8. using Android.OS;  
  9. using SupportToolbar = Android.Support.V7.Widget.Toolbar;  
  10. using Android.Support.V7.App;  
  11. using Android.Support.V4.Widget;  
  12. using System.Collections.Generic;  
  13. using Android.Support.V4.App;  
  14. using Android;  
  15. using DrawerLayout_V7_Tutorial;  
  16. using Android.Support.V7.Widget;  
  17. using Android.Support.Design.Widget;  
  18. using VAMOS.Droid.Fragments;  
  19. using Android.Support.V4.View;  
  20. using Android.Content.Res;  
  21.   
  22. namespace DrawerSample  
  23. {  
  24.     [Activity(Label = "SlidingPane Sample", Icon = "@drawable/icon", Theme = "@style/MyTheme")]  
  25.     public class SlidingPaneLayoutActivity : AppCompatActivity  
  26.     {  
  27.         //Declaring Variables to access throught this activity  
  28.         DrawerLayout drawerLayout;  
  29.         NavigationView navigationView;  
  30.         IMenuItem previousItem;  
  31.         Android.Support.V7.App.ActionBarDrawerToggle toggle;  
  32.   
  33.         protected override void OnCreate(Bundle savedInstanceState)  
  34.         {  
  35.             base.OnCreate(savedInstanceState);  
  36.             SetContentView(VAMOS.Droid.Resource.Layout.Dashboard);  
  37.             //Finding toolbar and adding to actionbar  
  38.             var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(VAMOS.Droid.Resource.Id.toolbar);  
  39.             SetSupportActionBar(toolbar);  
  40.             //For showing back button  
  41.             SupportActionBar.SetDisplayHomeAsUpEnabled(true);  
  42.             SupportActionBar.SetHomeButtonEnabled(true);  
  43.             SupportActionBar.SetDisplayShowTitleEnabled(false);  
  44.             //setting Hamburger icon Here  
  45.             SupportActionBar.SetHomeAsUpIndicator(VAMOS.Droid.Resource.Drawable.ic_menu);  
  46.             //Getting Drawer Layout declared in UI and handling closing and open events  
  47.             drawerLayout = FindViewById<DrawerLayout>(VAMOS.Droid.Resource.Id.drawer_layout);  
  48.             drawerLayout.DrawerOpened += DrawerLayout_DrawerOpened;  
  49.             drawerLayout.DrawerClosed += DrawerLayout_DrawerClosed;  
  50.             navigationView = FindViewById<NavigationView>(VAMOS.Droid.Resource.Id.nav_view);  
  51.             toggle = new Android.Support.V7.App.ActionBarDrawerToggle  
  52.             (  
  53.                     this,  
  54.                     drawerLayout,  
  55.                     VAMOS.Droid.Resource.String.openDrawer,  
  56.                     VAMOS.Droid.Resource.String.closeDrawer  
  57.             );  
  58.             drawerLayout.AddDrawerListener(toggle);  
  59.             //Synchronize the state of the drawer indicator/affordance with the linked DrawerLayout  
  60.             toggle.SyncState();  
  61.             //Handling click events on Menu items  
  62.             navigationView.NavigationItemSelected += (sender, e) =>  
  63.             {  
  64.   
  65.                 if (previousItem != null)  
  66.                     previousItem.SetChecked(false);  
  67.   
  68.                 navigationView.SetCheckedItem(e.MenuItem.ItemId);  
  69.   
  70.                 previousItem = e.MenuItem;  
  71.   
  72.                 switch (e.MenuItem.ItemId)  
  73.                 {  
  74.                     case VAMOS.Droid.Resource.Id.nav_home:  
  75.                         ListItemClicked(0);  
  76.                         break;  
  77.                     case VAMOS.Droid.Resource.Id.nav_friends:  
  78.                         ListItemClicked(1);  
  79.                         break;  
  80.                     case VAMOS.Droid.Resource.Id.nav_profile:  
  81.                         ListItemClicked(2);  
  82.                         break;  
  83.                 }  
  84.   
  85.   
  86.   
  87.                 drawerLayout.CloseDrawers();  
  88.             };  
  89.         }  
  90.   
  91.   
  92.         private void DrawerLayout_DrawerClosed(object sender, DrawerLayout.DrawerClosedEventArgs e)  
  93.         {  
  94.             //SupportActionBar.SetHomeAsUpIndicator(VAMOS.Droid.Resource.Drawable.ic_menu);  
  95.         }  
  96.   
  97.         private void DrawerLayout_DrawerOpened(object sender, DrawerLayout.DrawerOpenedEventArgs e)  
  98.         {  
  99.            // SupportActionBar.SetHomeAsUpIndicator(VAMOS.Droid.Resource.Drawable.ic_back);  
  100.         }  
  101.   
  102.         private void ListItemClicked(int position)  
  103.         {  
  104.             Android.Support.V4.App.Fragment fragment = null;  
  105.             switch (position)  
  106.             {  
  107.                 case 0:  
  108.                     fragment = new LoginFragment();  
  109.                     break;  
  110.                 case 1:  
  111.                     fragment = new Signupfragment();  
  112.                     break;  
  113.             }  
  114.             if (fragment != null)  
  115.             {  
  116.                 SupportFragmentManager.BeginTransaction()  
  117.                                .Replace(VAMOS.Droid.Resource.Id.content_frame, fragment)  
  118.                                .Commit();  
  119.             }  
  120.              
  121.              
  122.         }  
  123.   
  124.         //Handling Back Key Press  
  125.         public override void OnBackPressed()  
  126.         {  
  127.             if (drawerLayout.IsDrawerOpen((int)GravityFlags.Start))  
  128.             {  
  129.                 drawerLayout.CloseDrawer((int)GravityFlags.Start);  
  130.             }  
  131.             else  
  132.             {  
  133.                 base.OnBackPressed();  
  134.             }  
  135.         }  
  136.   
  137.         public override bool OnOptionsItemSelected(IMenuItem item)  
  138.         {  
  139.             switch (item.ItemId)  
  140.             {  
  141.                 case Android.Resource.Id.Home:  
  142.                     drawerLayout.OpenDrawer(Android.Support.V4.View.GravityCompat.Start);  
  143.                     return true;  
  144.             }  
  145.             return base.OnOptionsItemSelected(item);  
  146.         }  
  147.   
  148.         //Resposnible for mainting state,suppose if you suddenly rotated screen than drawer should not losse it context so you have save drawer states like below  
  149.         protected override void OnPostCreate(Bundle savedInstanceState)  
  150.         {  
  151.   
  152.             base.OnPostCreate(savedInstanceState);  
  153.             toggle.SyncState();  
  154.   
  155.         }  
  156.         public override void OnConfigurationChanged(Configuration newConfig)  
  157.         {  
  158.             base.OnConfigurationChanged(newConfig);  
  159.             toggle.OnConfigurationChanged(newConfig);  
  160.         }  
  161.          
  162.     }  
  163.       
  164. }  

Note

The following code is used to show Back button -

SupportActionBar.SetDisplayHomeAsUpEnabled(true); SupportActionBar.SetHomeButtonEnabled(true);

Here, I am setting Hamburger menu icon -

SupportActionBar.SetHomeAsUpIndicator(VAMOS.Droid.Resource.Drawable.ic_menu);

Step 4 - Creating Fragments

So, fragments are like reusable UI Controls. Add another two Layout files -  Login.axml and SignUp.axml

For now, I am keeping this UI empty. If you want, you can go ahead and write in the UI what you want to show.

Xamarin

Xamarin

  1. public class LoginFragment : Fragment  
  2.    {  
  3.         
  4.        public  LoginFragment()  
  5.        {  
  6.   
  7.        }  
  8.   
  9.        public override void OnCreate(Bundle savedInstanceState)  
  10.        {  
  11.            base.OnCreate(savedInstanceState);  
  12.             
  13.        }  
  14.   
  15.        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)  
  16.        {  
  17.            var view = inflater.Inflate(Resource.Layout.Login, container, false);  
  18.            return view;  
  19.        }   }  

Create the above same code for SignUpFragment and just change

  1. var view = inflater.Inflate(Resource.Layout.Login, container, false);  
  2.   
  3. //To  
  4.   
  5. var view = inflater.Inflate(Resource.Layout.Signup, container, false);  

So, whenever you click, we pass the Fragments to Framelayout to switch like this.

  1. private void ListItemClicked(int position)  
  2.        {  
  3.            Android.Support.V4.App.Fragment fragment = null;  
  4.            switch (position)  
  5.            {  
  6.                case 0:  
  7.                    fragment = new LoginFragment();  
  8.                    break;  
  9.                case 1:  
  10.                    fragment = new Signupfragment();  
  11.                    break;  
  12.            }  
  13.            if (fragment != null)  
  14.            {  
  15.                SupportFragmentManager.BeginTransaction()  
  16.                               .Replace(VAMOS.Droid.Resource.Id.content_frame, fragment)  
  17.                               .Commit();  
  18.            }  
  19.             
  20.             
  21.        }  

Final Result

Here, Orders and Redeem refers to Login and Signup respectively.

Xamarin

I hope you understood clearly. Please share your thoughts.