Google I/O 2015 has brought a whole new set of tools for Android Developers which are meant to make our lives easier. I´d like to devote a set of articles to talk about the incredibly useful Design Support Library.
For Material Design tutorial check this link.
In this article, I’ll start talking about the Navigation View. Since Material Design was released, we were given a standard definition on how a Navigation Drawer must look and feel. Truth is that implementing those guidelines was rather time consuming. But now, with the navigation view, the implementation is much easier.
Navigation View represents a standard navigation menu for application. The menu contents can be populated by a menu resource file. NavigationView is typically placed inside a DrawerLayout
.
We had done Navigation Drawer in earlier articles but this is too easy and too awesome.
Navigation View Xml structure:
1 2 3 4 5 6 7 |
<android.support.design.widget.NavigationView android:id="@+id/slider_menu" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/navigation_menu" app:header="@layout/header" /> |
In this tutorial, we are going to learn how to implement Navigation View with default and custom way.
1. Create a new project in Android Studio by navigating to File ⇒ New ⇒ New Project and fill required details. By default my activity is MainActivity.java.
2. Open build.gradle and include this libraries show below:
1 2 3 4 5 |
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:design:23.1.1' } |
3. Open res ⇒ values and create a new xml file naming colors.xml and add the following colors to it.
1 2 3 4 5 6 |
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#009688</color> <color name="colorPrimaryDark">#00796B</color> <color name="colorAccent">#4DB6AC</color> </resources> |
4. Open strings.xml located under res=>values folder and add following strings.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<resources> <string name="app_name">NavigationView Demo</string> <string name="default_navigation_view">Default Navigation View</string> <string name="custom_navigation_view">Custom Navigation View</string> <string name="drawer_open">Drawer Open</string> <string name="drawer_close">Drawer Close</string> <string name="others">Others</string> <!-- Navigation View String Values --> <string name="home">Home</string> <string name="my_account">My Account</string> <string name="chat">Chat</string> <string name="notification">Notification</string> <string name="share">Share App</string> <string name="rate">Rate App</string> <string name="settings">Settings</string> <string name="help">Help</string> </resources> |
5. Create a xml for toolbar naming toolbar.xml.
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:local="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" android:elevation="4dp" local:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" > </android.support.v7.widget.Toolbar> |
6. Since we are going to learn default and custom navigation view, so we need to create two xml files for this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include android:id="@+id/main_toolbar" layout="@layout/toolbar" /> <FrameLayout android:id="@+id/frame_container" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> <!-- Navigation View--> <android.support.design.widget.NavigationView android:id="@+id/slider_menu" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/navigation_menu" /> </android.support.v4.widget.DrawerLayout> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include android:id="@+id/main_toolbar" layout="@layout/toolbar" /> <FrameLayout android:id="@+id/frame_container" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> <!-- Navigation View--> <android.support.design.widget.NavigationView android:id="@+id/slider_menu" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:itemIconTint="@drawable/navigation_menu_selector" app:itemTextColor="@drawable/navigation_menu_selector" app:menu="@menu/navigation_menu" /> </android.support.v4.widget.DrawerLayout> |
7. In custom_navigation_view.xml we are using drawable navigation_menu_selector i.e. custom selector, so now create a new xml file under drawable resource naming navigation_menu_selector.xml and add the following code:
1 2 3 4 5 6 7 |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- This is used when the Navigation Item is checked --> <item android:color="#E91E63" android:state_checked="true" /> <!-- This is the default text color --> <item android:color="@android:color/black" /> </selector> |
8. For menu items for Navigation View we need to create a new menu under menu directory naming navigation_menu.xml and add the following menus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Main Menus --> <group android:checkableBehavior="single"> <item android:id="@+id/home" android:checkable="true" android:checked="true" android:icon="@drawable/ic_home" android:title="@string/home" /> <item android:id="@+id/my_account" android:checkable="true" android:checked="false" android:icon="@drawable/ic_my_account" android:title="@string/my_account" /> <item android:id="@+id/notifications" android:checkable="true" android:checked="false" android:icon="@drawable/ic_notification" android:title="@string/notification" /> <item android:id="@+id/chat" android:checkable="true" android:checked="false" android:icon="@drawable/ic_chat" android:title="@string/chat" /> </group> <!-- Sub Menus --> <item android:title="@string/others"> <menu> <group android:checkableBehavior="none"> <item android:id="@+id/share_app" android:icon="@drawable/ic_share" android:title="@string/share" /> <item android:id="@+id/rate_app" android:icon="@drawable/ic_rate" android:title="@string/rate" /> <item android:id="@+id/settings" android:icon="@drawable/ic_settings" android:title="@string/settings" /> <item android:id="@+id/help" android:icon="@drawable/ic_help" android:title="@string/help" /> </group> </menu> </item> </menu> |
For menu icons you can download form Icons8 site and size should be 24px.
9. Now for Header View of Navigation View create new layout xml file naming header_view.xml and add your header UI in these xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/sellers_profile_layout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@android:color/white"> <!-- Header View --> <ImageView android:id="@+id/image_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_margin="10dp" android:src="@drawable/ic_user" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@+id/image_view" android:orientation="vertical" android:paddingBottom="15dp" android:paddingRight="15dp" android:paddingTop="15dp"> <TextView android:id="@+id/username" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:text="Dr. Droid" android:textColor="@android:color/black" android:textSize="15sp" /> <TextView android:id="@+id/email_address" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:text="androhub.com" android:textColor="@android:color/black" android:textSize="13sp" /> </LinearLayout> <View android:layout_width="fill_parent" android:layout_height="1dp" android:layout_alignParentBottom="true" android:background="@android:color/darker_gray" /> </RelativeLayout> |
10. Now create activity_main.xml that contains two button for starting default and custom navigation view activity.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" android:padding="10dp"> <Button android:id="@+id/default_navigation_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/default_navigation_view" android:textColor="#000000" android:textSize="15sp" /> <Button android:id="@+id/custom_navigation_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/custom_navigation_view" android:textColor="#000000" android:textSize="15sp" /> </LinearLayout> |
11. Now create a java class naming MainActivity.java and add the following code. In this class we are just starting NavigationView_Activity class by passing boolean data type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
package com.navigationview_demo; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.default_navigation_view).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startNavigationViewActivity(true); } }); findViewById(R.id.custom_navigation_view).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startNavigationViewActivity(false); } }); } /* Start Navigation View activity */ private void startNavigationViewActivity(boolean value) { Intent in = new Intent(MainActivity.this, NavigationView_Activity.class); in.putExtra("value", value); startActivity(in); } } |
12. Now mainly create NavigationMenu_Activity.java and add the following code. In this code there is nothing to do with navigation view because we already set menu items in xml layout. So here we are just going to implement navigation view menu item click listener.
For using header view for changing text or images you can refer to setUpHeaderView() in this class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
package com.navigationview_demo; import android.content.res.Configuration; import android.os.Bundle; import android.support.design.widget.NavigationView; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Gravity; import android.view.MenuItem; import android.view.View; import android.widget.TextView; import android.widget.Toast; /** * Created by SONU on 21/03/16. */ public class NavigationView_Activity extends AppCompatActivity { private static DrawerLayout mDrawerLayout; private static ActionBarDrawerToggle mDrawerToggle; private static Toolbar toolbar; private static FragmentManager fragmentManager; private static NavigationView navigationView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //Get boolean data value from intent boolean isDefaultNavigationView = getIntent().getBooleanExtra("value", false); //according to boolean value set content view if (isDefaultNavigationView) setContentView(R.layout.default_navigation_view_activity); else setContentView(R.layout.custom_navigation_view_activity); initViews(); setUpHeaderView(); onMenuItemSelected(); //At start set home fragment if (savedInstanceState == null) { navigationView.setCheckedItem(R.id.home); MenuItem item = navigationView.getMenu().findItem(R.id.home); setFragment(item); } } /* Init all views */ private void initViews() { toolbar = (Toolbar) findViewById(R.id.main_toolbar); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); navigationView = (NavigationView) findViewById(R.id.slider_menu); fragmentManager = getSupportFragmentManager(); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, // nav menu toggle icon R.string.drawer_open, // nav drawer open - description for // accessibility R.string.drawer_close // nav drawer close - description for // accessibility ) { public void onDrawerClosed(View view) { } public void onDrawerOpened(View drawerView) { } }; mDrawerLayout.setDrawerListener(mDrawerToggle); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Pass any configuration change to the drawer toggls mDrawerToggle.onConfigurationChanged(newConfig); } /** * For using header view use this method **/ private void setUpHeaderView() { View headerView = navigationView.inflateHeaderView(R.layout.header_view); TextView textOne = (TextView) headerView.findViewById(R.id.username); TextView textTwo = (TextView) headerView.findViewById(R.id.email_address); } /* Method for Navigation View item selection */ private void onMenuItemSelected() { navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem item) { //Check and un-check menu item if they are checkable behaviour if (item.isCheckable()) { if (item.isChecked()) item.setChecked(false); else item.setChecked(true); } //Closing drawer on item click mDrawerLayout.closeDrawers(); switch (item.getItemId()) { case R.id.home: //Replace fragment setFragment(item); break; case R.id.my_account: //Replace fragment setFragment(item); break; case R.id.chat: //Replace fragment setFragment(item); break; case R.id.notifications: //Replace fragment setFragment(item); break; case R.id.share_app: //Start new Activity or do your stuff Toast.makeText(NavigationView_Activity.this, "You Clicked on "" + item.getTitle().toString() + "" menu item.", Toast.LENGTH_SHORT).show(); break; case R.id.rate_app: //Start new Activity or do your stuff Toast.makeText(NavigationView_Activity.this, "You Clicked on "" + item.getTitle().toString() + "" menu item.", Toast.LENGTH_SHORT).show(); break; case R.id.settings: //Start new Activity or do your stuff Toast.makeText(NavigationView_Activity.this, "You Clicked on "" + item.getTitle().toString() + "" menu item.", Toast.LENGTH_SHORT).show(); break; case R.id.help: //Start new Activity or do your stuff Toast.makeText(NavigationView_Activity.this, "You Clicked on "" + item.getTitle().toString() + "" menu item.", Toast.LENGTH_SHORT).show(); break; } return false; } }); } /* Set Fragment, setting toolbar title and passing item title via bundle to fragments*/ public void setFragment(MenuItem item) { toolbar.setTitle(item.getTitle()); //Find fragment by tag Fragment fr = fragmentManager.findFragmentByTag(item.getTitle().toString()); Fragment dummyFragment = new Dummy_Fragment(); Bundle b = new Bundle(); //If fragment is null replace fragment if (fr == null) { b.putString("data", item.getTitle().toString()); dummyFragment.setArguments(b);//Set Arguments fragmentManager .beginTransaction() .replace(R.id.frame_container, dummyFragment, item.getTitle().toString()) .commit(); } } //On back press check if drawer is open and closed @Override public void onBackPressed() { if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) mDrawerLayout.closeDrawers(); else super.onBackPressed(); } } |
13. We are using Dummy_Fragment in above step so we need to create a xml file naming dummy_fragment.xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <TextView android:id="@+id/fragment_textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:padding="15dp" android:textColor="@android:color/black" android:textSize="17sp" /> </LinearLayout> |
14. For xml dummy_fragment create a java file naming Dummy_Fragment.java and add the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package com.navigationview_demo; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; /** * Created by SONU on 21/03/16. */ public class Dummy_Fragment extends Fragment { public Dummy_Fragment() { } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.dummy_fragment, container, false); TextView text = (TextView) view.findViewById(R.id.fragment_textview); //Get bundle data from arguments and set text over textview String title = getArguments().getString("data"); text.setText(title); return view; } } |
15. Don’t forget to declare your NavigationView_Activity inside AndroidManifest.xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.navigationview_demo"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".NavigationView_Activity" /> </application> </manifest> |
16. Some important codes of NavigationView:
1 |
View headerView = navigationView.inflateHeaderView(R.layout.header_view); |
– for api level 23+
1 |
navigationView.setCheckedItem(R.id.home); |
– for api level below 23
1 |
navigationView.getMenu().getItem(0).setChecked(true); |
** where ‘0’ is the index of the menu item.
1 |
MenuItem item = navigationView.getMenu().findItem(R.id.home); |
17. Finally, all done – now develop an awesome app using navigation view.
Thanks.
Subscribe to us and get the latest news.
8 Comments
madhav
Monday, August 8th, 2016option menus are not enable how can i display them and put operations on it.
Dr. Droid
Monday, August 8th, 2016Hi Madhav,
Which option menus you are talking about here can you elaborate it?
Thanks
madhav
Monday, August 8th, 2016action bar menus like search ,settings,etc.. how to add them.
Dr. Droid
Monday, August 8th, 2016Check this link : https://www.androhub.com/android-actionbar-and-option-menus/
thanks
Abhijit
Thursday, November 16th, 2017hey Nice tutorial
But how to add another fragment in Navigation view
Dr. Droid
Thursday, November 16th, 2017Hi Abhijit,
Create a new fragment like Dummy Fragment and replace that fragment on navigation item click.
Thanks
Abhijit
Friday, November 17th, 2017Hello, sir just said like you I have created 2 more fragments but how to include in navigation view, can you give some example to understand.
Dr. Droid
Friday, November 17th, 2017Hi Abhijit,
Use the below code and call the below code on item click event of navigation view:
toolbar.setTitle(item.getTitle());
//Find fragment by tag
Fragment fr = fragmentManager.findFragmentByTag(item.getTitle().toString());
Fragment yourFragment = new FragmentName();
Bundle b = new Bundle();
//If fragment is null replace fragment
if (fr == null) {
b.putString(“data”, item.getTitle().toString());
dummyFragment.setArguments(b);//Set Arguments
fragmentManager
.beginTransaction()
.replace(R.id.frame_container,
yourFragment, item.getTitle().toString())
.commit();
}
Thanks