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. <style name="MyDrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
  10. <item name="color">#F5F5F5</item>
  11. <item name="spinBars">true</item>
  12. </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. <android.support.v4.widget.DrawerLayout
  17. android:id="@+id/drawer_layout"
  18. android:layout_width="match_parent"
  19. android:layout_height="match_parent">
  20. <!-- The Main Content View -->
  21. <RelativeLayout
  22. android:layout_width="match_parent"
  23. android:layout_height="match_parent">
  24. <android.support.design.widget.AppBarLayout
  25. android:layout_height="wrap_content"
  26. android:layout_width="match_parent"
  27. android:id="@+id/toolbar_layout">
  28. <!-- you can create separately and use it here Like this ,but for now i am doing inline for toolbar-->
  29. <!--<include
  30. layout="@layout/toolbar" />-->
  31. </android.support.design.widget.AppBarLayout>
  32. <FrameLayout
  33. android:id="@+id/content_frame"
  34. android:layout_below="@id/toolbar_layout"
  35. android:layout_width="match_parent"
  36. android:layout_height="match_parent" />
  37. </RelativeLayout>
  38. <!-- The Left Navigation Drawer -->
  39. <android.support.design.widget.NavigationView
  40. android:id="@+id/nav_view"
  41. android:layout_height="match_parent"
  42. android:layout_width="240dp"
  43. android:layout_gravity="start"
  44. app:menu="@layout/left_menu_items"
  45. app:headerLayout="@layout/nav_header_main"
  46. android:fitsSystemWindows="true" >
  47. </android.support.design.widget.NavigationView>
  48. </android.support.v4.widget.DrawerLayout>
  49. </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. <refractored.controls.CircleImageView
  17. xmlns:app="http://schemas.android.com/apk/res-auto"
  18. android:id="@+id/profile_image"
  19. android:layout_width="96dp"
  20. android:layout_height="96dp"
  21. android:src="@drawable/profile"
  22. app:civ_border_width="2dp"
  23. app:civ_border_color="#D40047"/>
  24. <TextView
  25. android:id="@+id/name"
  26. android:text="Nina"
  27. android:textColor="#1E1E1E"
  28. android:layout_width="match_parent"
  29. android:layout_height="wrap_content"
  30. android:paddingTop="@dimen/nav_header_vertical_spacing"
  31. android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
  32. <TextView
  33. android:id="@+id/names"
  34. android:layout_below="@id/name"
  35. android:text="[email protected]"
  36. android:textColor="#B0B0B0"
  37. android:layout_width="match_parent"
  38. android:layout_height="wrap_content"
  39. android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
  40. </LinearLayout>
  41. </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. <group android:checkableBehavior="single">
  4. <item
  5. android:id="@+id/nav_home"
  6. android:icon="@drawable/ic_Order"
  7. android:title="Orders" />
  8. <item
  9. android:id="@+id/nav_friends"
  10. android:icon="@drawable/ic_Redeem"
  11. android:title="Redeem" />
  12. <item
  13. android:id="@+id/nav_profile"
  14. android:icon="@drawable/ic_today"
  15. android:title="Notifications" />
  16. </group>
  17. <item android:title="Today">
  18. <menu>
  19. <item
  20. android:icon="@drawable/ic_test"
  21. android:title="Tasks"
  22. android:checkable="true" />
  23. <item
  24. android:icon="@drawable/ic_forum"
  25. android:title="Messages"
  26. android:checkable="true" />
  27. </menu>
  28. </item>
  29. </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. using Android.App;
  3. using Android.Content;
  4. using Android.Runtime;
  5. using Android.Views;
  6. using Android.Widget;
  7. using Android.OS;
  8. using SupportToolbar = Android.Support.V7.Widget.Toolbar;
  9. using Android.Support.V7.App;
  10. using Android.Support.V4.Widget;
  11. using System.Collections.Generic;
  12. using Android.Support.V4.App;
  13. using Android;
  14. using DrawerLayout_V7_Tutorial;
  15. using Android.Support.V7.Widget;
  16. using Android.Support.Design.Widget;
  17. using VAMOS.Droid.Fragments;
  18. using Android.Support.V4.View;
  19. using Android.Content.Res;
  20. namespace DrawerSample
  21. {
  22. [Activity(Label = "SlidingPane Sample", Icon = "@drawable/icon", Theme = "@style/MyTheme")]
  23. public class SlidingPaneLayoutActivity : AppCompatActivity
  24. {
  25. //Declaring Variables to access throught this activity
  26. DrawerLayout drawerLayout;
  27. NavigationView navigationView;
  28. IMenuItem previousItem;
  29. Android.Support.V7.App.ActionBarDrawerToggle toggle;
  30. protected override void OnCreate(Bundle savedInstanceState)
  31. {
  32. base.OnCreate(savedInstanceState);
  33. SetContentView(VAMOS.Droid.Resource.Layout.Dashboard);
  34. //Finding toolbar and adding to actionbar
  35. var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(VAMOS.Droid.Resource.Id.toolbar);
  36. SetSupportActionBar(toolbar);
  37. //For showing back button
  38. SupportActionBar.SetDisplayHomeAsUpEnabled(true);
  39. SupportActionBar.SetHomeButtonEnabled(true);
  40. SupportActionBar.SetDisplayShowTitleEnabled(false);
  41. //setting Hamburger icon Here
  42. SupportActionBar.SetHomeAsUpIndicator(VAMOS.Droid.Resource.Drawable.ic_menu);
  43. //Getting Drawer Layout declared in UI and handling closing and open events
  44. drawerLayout = FindViewById<DrawerLayout>(VAMOS.Droid.Resource.Id.drawer_layout);
  45. drawerLayout.DrawerOpened += DrawerLayout_DrawerOpened;
  46. drawerLayout.DrawerClosed += DrawerLayout_DrawerClosed;
  47. navigationView = FindViewById<NavigationView>(VAMOS.Droid.Resource.Id.nav_view);
  48. toggle = new Android.Support.V7.App.ActionBarDrawerToggle
  49. (
  50. this,
  51. drawerLayout,
  52. VAMOS.Droid.Resource.String.openDrawer,
  53. VAMOS.Droid.Resource.String.closeDrawer
  54. );
  55. drawerLayout.AddDrawerListener(toggle);
  56. //Synchronize the state of the drawer indicator/affordance with the linked DrawerLayout
  57. toggle.SyncState();
  58. //Handling click events on Menu items
  59. navigationView.NavigationItemSelected += (sender, e) =>
  60. {
  61. if (previousItem != null)
  62. previousItem.SetChecked(false);
  63. navigationView.SetCheckedItem(e.MenuItem.ItemId);
  64. previousItem = e.MenuItem;
  65. switch (e.MenuItem.ItemId)
  66. {
  67. case VAMOS.Droid.Resource.Id.nav_home:
  68. ListItemClicked(0);
  69. break;
  70. case VAMOS.Droid.Resource.Id.nav_friends:
  71. ListItemClicked(1);
  72. break;
  73. case VAMOS.Droid.Resource.Id.nav_profile:
  74. ListItemClicked(2);
  75. break;
  76. }
  77. drawerLayout.CloseDrawers();
  78. };
  79. }
  80. private void DrawerLayout_DrawerClosed(object sender, DrawerLayout.DrawerClosedEventArgs e)
  81. {
  82. //SupportActionBar.SetHomeAsUpIndicator(VAMOS.Droid.Resource.Drawable.ic_menu);
  83. }
  84. private void DrawerLayout_DrawerOpened(object sender, DrawerLayout.DrawerOpenedEventArgs e)
  85. {
  86. // SupportActionBar.SetHomeAsUpIndicator(VAMOS.Droid.Resource.Drawable.ic_back);
  87. }
  88. private void ListItemClicked(int position)
  89. {
  90. Android.Support.V4.App.Fragment fragment = null;
  91. switch (position)
  92. {
  93. case 0:
  94. fragment = new LoginFragment();
  95. break;
  96. case 1:
  97. fragment = new Signupfragment();
  98. break;
  99. }
  100. if (fragment != null)
  101. {
  102. SupportFragmentManager.BeginTransaction()
  103. .Replace(VAMOS.Droid.Resource.Id.content_frame, fragment)
  104. .Commit();
  105. }
  106. }
  107. //Handling Back Key Press
  108. public override void OnBackPressed()
  109. {
  110. if (drawerLayout.IsDrawerOpen((int)GravityFlags.Start))
  111. {
  112. drawerLayout.CloseDrawer((int)GravityFlags.Start);
  113. }
  114. else
  115. {
  116. base.OnBackPressed();
  117. }
  118. }
  119. public override bool OnOptionsItemSelected(IMenuItem item)
  120. {
  121. switch (item.ItemId)
  122. {
  123. case Android.Resource.Id.Home:
  124. drawerLayout.OpenDrawer(Android.Support.V4.View.GravityCompat.Start);
  125. return true;
  126. }
  127. return base.OnOptionsItemSelected(item);
  128. }
  129. //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
  130. protected override void OnPostCreate(Bundle savedInstanceState)
  131. {
  132. base.OnPostCreate(savedInstanceState);
  133. toggle.SyncState();
  134. }
  135. public override void OnConfigurationChanged(Configuration newConfig)
  136. {
  137. base.OnConfigurationChanged(newConfig);
  138. toggle.OnConfigurationChanged(newConfig);
  139. }
  140. }
  141. }

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. public LoginFragment()
  4. {
  5. }
  6. public override void OnCreate(Bundle savedInstanceState)
  7. {
  8. base.OnCreate(savedInstanceState);
  9. }
  10. public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
  11. {
  12. var view = inflater.Inflate(Resource.Layout.Login, container, false);
  13. return view;
  14. } }

Create the above same code for SignUpFragment and just change

  1. var view = inflater.Inflate(Resource.Layout.Login, container, false);
  2. //To
  3. 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. }

Final Result

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

Xamarin

I hope you understood clearly. Please share your thoughts.