January 31, 2016

Navigation Drawer using material design in Xamarin.Android.

In Brief:  Here you can see the Navigation drawer implementation in Xamarin android with simple steps and reduced code using beautiful material design.




In my previous post explained Sliding menu in xamarin.android  using Animation and Gesture detection,Sliding menu in Xamarin.iOS using GestureRecognizer,CATransition and Animation,Push notification using Google Cloud Messaging(GCM) in Xamarin.Android.

In Detail:
Navigation drawer not only provides the beautiful UI look to the app but also a great way for navigating within the different app section. Even the Google make use of the same in its applications.

In Steps:

1. Add Latest Android Support Design Library
Provide the backward compatibility to the app. To do so add the following components to the project.
a.) Android Support design library
b.)Android Support V7
c.)Android Support V4
2. Add Style Inheriting from Theme.AppCompat
<?xml version="1.0" encoding="UTF-8" ?>
<resources>
   <style name="MyTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
     <item name="windowNoTitle">true</item>
     <item name="windowActionBar">false</item>
     <item name="colorPrimary">#2196F3</item>
     <item name="colorPrimaryDark">#1976D2</item>
     <item name="colorAccent">#FF4081</item>
   </style>
   <style name="MyTheme" parent="MyTheme.Base">
   </style>
</resources>

3. Create Layout file
In a layout file define android.support.v4.widget.DrawerLayout as root layout.
To display Fly-out/In menu add  android.support.design.widget.NavigationView. Which defines two special properties called headerLayout and menu. Here as the name indicates
headerLayout : lets us to define custom layout file for navigation view header part and attach with this property.
menu : Define menu text for navigation view in xml file and reference with this property.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:minWidth="25px"
    android:minHeight="25px"
    android:fitsSystemWindows="true">
    <android.support.v4.widget.DrawerLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:minWidth="25px"
        android:minHeight="25px"
        android:id="@+id/drawer_layout">
        <LinearLayout
            android:id="@+id/layout_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <include
                layout="@layout/app_bar" />
            <FrameLayout
                android:id="@+id/HomeFrameLayout"
                android:minWidth="25px"
                android:minHeight="25px"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>
        <android.support.design.widget.NavigationView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:id="@+id/nav_view"
            app:menu="@menu/navmenu"
            app:headerLayout="@layout/headerdrawerlayout" />
    </android.support.v4.widget.DrawerLayout>
</LinearLayout>

4. Prepare activity file
Add below coding by binding UI elements.
a. Initiate toolbar
b. To catch menu click event add listener to the NavigationView's NavigationItemSelected event.
c. Add action bar drawer toggle button.
d. Call SyncState() method to connect everything properly.

using Android.App;
using Android.Widget;
using Android.OS;
using Android.Support.Design.Widget;
using Android.Support.V4.Widget;
using Android.Support.V7.Widget; 
using Android.Support.V7.App;  

namespace TenantsForum
{
    [Activity (Label = "@string/app_name",ScreenOrientation=Android.Content.PM.ScreenOrientation.Portrait)]
 public class MainActivity : AppCompatActivity
 {
  DrawerLayout drawerLayout;
  protected override void OnCreate (Bundle savedInstanceState)
  {
   base.OnCreate (savedInstanceState);   

   SetContentView (Resource.Layout.Main);
   drawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);

   
   // Initialize toolbar
   var toolbar = FindViewById<Toolbar>(Resource.Id.app_bar);
   SetSupportActionBar(toolbar);
   SupportActionBar.SetTitle (Resource.String.app_name);
   SupportActionBar.SetDisplayHomeAsUpEnabled(true);
   SupportActionBar.SetDisplayShowHomeEnabled(true);

   // Attach item selected handler to navigation view
   var navigationView = FindViewById<NavigationView>(Resource.Id.nav_view);
   navigationView.NavigationItemSelected += NavigationView_NavigationItemSelected;

   // Create ActionBarDrawerToggle button and add it to the toolbar
   var drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, Resource.String.open_drawer, Resource.String.close_drawer);
   drawerLayout.SetDrawerListener(drawerToggle);
   drawerToggle.SyncState();
   
   //Load default screen
    var ft= FragmentManager.BeginTransaction ();
    ft.AddToBackStack (null);
    ft.Add (Resource.Id.HomeFrameLayout, new HomeFragment ());
    ft.Commit (); 

  }
  void NavigationView_NavigationItemSelected(object sender, NavigationView.NavigationItemSelectedEventArgs e)
  {
            switch (e.MenuItem.ItemId)
            {
                case (Resource.Id.nav_home): 
                 // React on 'nav_home' selection
                     break;
                case (Resource.Id.nav_messages):
                    //
                    break;
                case (Resource.Id.nav_friends):
                  // React on 'Friends' selection
                    break;  
            }
   // Close drawer
   drawerLayout.CloseDrawers();
  }
 }
}

Now your app should be decorated with beautiful android material design Navigation drawer.

Check out complete code in https://github.com/suchithm/NavigationDrawerMD

Thanks for your time here and feel free to post any issues/suggestions.

30 comments:

  1. sir, can u post how to launch an other app from our app via voice !

    ReplyDelete
    Replies
    1. Hi Suraj as of now i don't have much idea on this and noted with thanks.

      Delete
  2. Hi! i setup all these code in a very new app to avoid any confusion, but still it gives a run time error.
    Unhandled Exception:
    Java.Lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

    ReplyDelete
    Replies
    1. Hi, After completing step 2. mention theme in manifest file, application tag like android:theme="@style/MyTheme"

      Delete
  3. Hi,When I am trying to run the code urs given in github .Iam getting an exception like this
    "Android.Views.InflateException: Binary XML file line #1: Error inflating class android.support.design.widget.NavigationView ".

    ReplyDelete
    Replies
    1. Hi Madhushree, Update your support design library and all other package library, then rebuild the solution it should work.

      Delete
  4. Hello , Thank you for example , it is very useful .
    Could you please give me a hint How to implement tab (in fragment ) in this project that the main class inheriting AppCompatActivity ?

    ReplyDelete
    Replies
    1. Hi, check tab implementation using andriod material design here: http://www.appliedcodelog.com/2016/05/material-design-tab-in-xamarin-android.html

      Delete
  5. sir i have an warning message in <android.support.v4.widget.DrawerLayout it say
    The element 'LinearLayout' has invalid child element 'android.support.v4.widget.DrawerLayout'. List of possible elements expected
    what is going on ?
    can u help me solve it?
    i already ask google but it seam not help
    thx

    ReplyDelete
    Replies
    1. Hi thavaro,
      Ensure that you are included mentioned package in step1.

      Delete
  6. Hello? am getting no resource found that matches theme appcompat light darkactionbar.

    ReplyDelete
    Replies
    1. Hi, this error is related to support design and other related packages are not installed properly. Update the packages to the latest version and rebuild.

      Delete
  7. why id is not accepted in main activity?? id in axml file is not accepted in main activity?? can you please help me out

    ReplyDelete
    Replies
    1. Hi Bina, all axml id should be able to reference from activity. Here which id is you are talking about.

      Delete
    2. Hi Bina, all axml id should be able to reference from activity. Here which id is you are talking about.

      Delete
  8. why id is not accepted in main activity.cs which is define in axml file??

    ReplyDelete
  9. drawer_layout id is not accessible from mainactivity.cs. How to resolve that?

    ReplyDelete
    Replies
    1. Hi,Sagar
      Recheck your layout file for any syntax error. Clean and rebuild the solution.

      Delete
  10. Hi sir, im newbie, I dont know the step number 2. Add Style Inheriting from Theme.AppCompat

    Do you have tutorials in this blog about this? I mean I dont know the location of Theme.AppCompat. Thanks.

    ReplyDelete
    Replies
    1. Hi, Open Xamarin.Android Project ->Resources->Values right click Add->New file->XML name it as Style.xml , add step 2 style code

      Delete
  11. Hi Suchith, I got an error while building the project that in MainActiity DrawerLayout exists in both Xamarin.Android.Support.Core.UI and Xamarin.Android.Support.V4 ...
    Any idea to overcome this issue?
    I tried using specific
    using DrawerLayout=Xamarin.Android.Support.V4.Widget.DrawerLayout
    still same problem

    ReplyDelete
    Replies
    1. Hi Ishwor, i think there still conflict with loaded packages. you can check with inline namespace. like Xamarin.Android.Support.V4.Widget.DrawerLayout drawerLayout;

      Delete
    2. I made it work after struggling with libraries version problem.
      Now, I am not expert using fragments. I already have 3 activities I want to add in the menu as links.
      I have to add MainActivity code to every activity? but It would be restarting each time I call an activity when a menu item is clicked, right? What is the best approach for this?

      Delete
    3. Hi Luis,
      Here you have to make use of fragments as a child views for the menu selection. Activity can hold this Menu and can display fragments within in it.

      Delete
  12. How to open new page in the Fragment page when I click a button in the Fragmet page?

    ReplyDelete
    Replies
    1. Hi, If you have already some view in frame layout then you can Replace or else you can add:
      var ft= FragmentManager.BeginTransaction ();
      ft.AddToBackStack (null);
      ft.Add (Resource.Id.HomeFrameLayout, new HomeFragment ());
      ft.Commit ();

      Delete
  13. Hi Suchith,
    I haven't found the Android Support Library V4 in Xamarin Components(https://components.xamarin.com/view/xamandroidsupportv4-18). Can you suggest any other component.

    Regards,
    Ranjith

    ReplyDelete
    Replies
    1. Ya Ranjith, seems that link is not reachable now. You can find here https://components.xamarin.com/view/xamandroidsupportv4-18?version=23.1.1.0 or nuget package https://www.nuget.org/packages/Xamarin.Android.Support.v4/

      Delete