In this article, we will see how to develop an Android application containing sidebar navigation drawer menu with icons and counter. Here count specifies, how many times the drawer menu item is selected by the user since the application is opened.
In order to display ActionBar in legacy Android versions, we are making use ActionBarCompat library ( V7 ) . For navigation drawer library, we are making use Android Support Library ( V4 ) .
This application is developed in Eclipse 4.2.0 with Android SDK ( 22.2.1 ) and ADT plugin ( 22.2.1 ).
Screenshot of this application is available towards the end of this article.
1. Create an Android application project with the given below details
- Application Name : NavigationDrawerLegacy
- Project Name : NavigationDrawerLegacy
- Package Name : in.wptrafficanalyzer.navigationdrawerlegacy
- Minimum Required SDK : API 8 : Android 2.2 ( Froyo )
- Target SDK : API 18 : Android 4.3
- Compile With : API 18 : Android 4.3
- Theme : Holo Light with Dark Action Bar
2. Adding Android Support Library ( V4 )
By default, Android support library (android-support-v4.jar ) is added by Eclipse IDE to the directory libs. If it is not added, we can do it manually by doing the following steps :
- Open Project Explorer by Clicking “Window -> Show View -> Project Explorer”
- Right click this project
- Then from popup menu, Click “Android Tools -> Add Support Library “
3. Adding ActionBarCompat Support Library ( V7 )
Please refer the article titled “Android – Setting up ActionBarCompat support library in Eclipse”
4. Link this project to ActionBarCompat library
5. Download and extract the icon images to the directory res/drawable-mdpi
6. Update the file res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">NavigationDrawerLegacy</string> <string name="action_settings">Settings</string> <string name="hello_world">Hello world!</string> <string name="hello">Hello</string> <dimen name="count">10dp</dimen> <string name="drawer_open">Open navigation drawer</string> <string name="drawer_close">Close navigation drawer</string> <string-array name="countries"> <item>India</item> <item>Pakistan</item> <item>Sri Lanka</item> <item>China</item> <item>Bangladesh</item> <item>Nepal</item> <item>Afghanistan</item> <item>North Korea</item> <item>South Korea</item> <item>Japan</item> </string-array> </resources>
7. Create a Shape drawable in the file res/drawable/counter_shape.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <solid android:color="#EAEAEA"/> <corners android:bottomLeftRadius="20dp" android:topRightRadius="20dp" android:topLeftRadius="20dp" android:bottomRightRadius="20dp" /> </shape>
8. Create a Shape drawable in the file res/drawable/drawer_title_shape.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <solid android:color="#EAEAEA"/> <corners android:bottomLeftRadius="0dp" android:topRightRadius="0dp" android:topLeftRadius="0dp" android:bottomRightRadius="0dp" /> </shape>
9. Create a layout for the navigation drawer listview for legacy Android Versions ( API Level < 11 ) in the file res/layout/drawer_layout.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="60dp" > <ImageView android:id="@+id/flag" android:layout_width="40dp" android:layout_height="40dp" android:paddingLeft="10dp" android:paddingTop="10dp" android:paddingRight="10dp" android:paddingBottom="10dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:contentDescription="@string/hello" /> <TextView android:id="@+id/country" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/flag" android:layout_centerVertical="true" android:textSize="15sp" /> <TextView android:id="@+id/count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="@dimen/count" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:gravity="center" android:padding="0dp" android:background="@drawable/counter_shape" android:textSize="15sp" /> </RelativeLayout>
10. Create a layout for the navigation drawer listview for Android Versions ( API Level >= 11 ) in the file res/layout-v11/drawer_layout.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:background="?android:attr/activatedBackgroundIndicator" android:layout_height="60dp" > <ImageView android:id="@+id/flag" android:layout_width="40dp" android:layout_height="40dp" android:paddingLeft="10dp" android:paddingTop="10dp" android:paddingRight="10dp" android:paddingBottom="10dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:contentDescription="@string/hello" /> <TextView android:id="@+id/country" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/flag" android:layout_centerVertical="true" android:textSize="15sp" /> <TextView android:id="@+id/count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="@dimen/count" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:gravity="center" android:padding="0dp" android:background="@drawable/counter_shape" android:textSize="15sp" /> </RelativeLayout>
11. Create a layout file namely res/layout/fragment_layout.xml for the fragment CountryFragment
<?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:orientation="vertical" > <TextView android:id="@+id/tv_content" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:textSize="40sp" /> </LinearLayout>
12. Update the layout file res/layout/activity_main.xml to include navigation drawer in the MainActivity
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- The main content view --> <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- The navigation drawer --> <LinearLayout android:id="@+id/drawer" android:layout_width="240dp" android:layout_height="match_parent" android:orientation="vertical" android:layout_gravity="start" > <TextView android:layout_width="match_parent" android:layout_height="50dp" android:gravity="center" android:textSize="20sp" android:text="Country" android:background="@drawable/drawer_title_shape" /> <ListView android:id="@+id/drawer_list" android:layout_width="match_parent" android:layout_height="match_parent" android:choiceMode="singleChoice" android:divider="@android:color/darker_gray" android:dividerHeight="0.1dp" android:textColor="@android:color/white" android:background="#fff" /> </LinearLayout> </android.support.v4.widget.DrawerLayout>
13. Create a fragment class namely CountryFragment in the file src/in/wptrafficanalyzer/navigationdrawerlegacy/CountryFragment.java
package in.wptrafficanalyzer.navigationdrawerlegacy; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class CountryFragment extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Retrieving the currently selected item number int position = getArguments().getInt("position"); // List of rivers String[] countries = getResources().getStringArray(R.array.countries); // Creating view correspoding to the fragment View v = inflater.inflate(R.layout.fragment_layout, container, false); // Getting reference to the TextView of the Fragment TextView tv = (TextView) v.findViewById(R.id.tv_content); // Setting currently selected river name in the TextView tv.setText(countries[position]); return v; } }
14. Update the file src/in/wptrafficanalyzer/navigationdrawerlegacy/MainActivity.java
package in.wptrafficanalyzer.navigationdrawerlegacy; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import android.os.Bundle; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; public class MainActivity extends ActionBarActivity { int mPosition = -1; String mTitle = ""; // Array of strings storing country names String[] mCountries ; // Array of integers points to images stored in /res/drawable-ldpi/ int[] mFlags = new int[]{ R.drawable.india, R.drawable.pakistan, R.drawable.srilanka, R.drawable.china, R.drawable.bangladesh, R.drawable.nepal, R.drawable.afghanistan, R.drawable.nkorea, R.drawable.skorea, R.drawable.japan }; // Array of strings to initial counts String[] mCount = new String[]{ "", "", "", "", "", "", "", "", "", "" }; private DrawerLayout mDrawerLayout; private ListView mDrawerList; private ActionBarDrawerToggle mDrawerToggle; private LinearLayout mDrawer ; private List<HashMap<String,String>> mList ; private SimpleAdapter mAdapter; final private String COUNTRY = "country"; final private String FLAG = "flag"; final private String COUNT = "count"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Getting an array of country names mCountries = getResources().getStringArray(R.array.countries); // Title of the activity mTitle = (String)getTitle(); // Getting a reference to the drawer listview mDrawerList = (ListView) findViewById(R.id.drawer_list); // Getting a reference to the sidebar drawer ( Title + ListView ) mDrawer = ( LinearLayout) findViewById(R.id.drawer); // Each row in the list stores country name, count and flag mList = new ArrayList<HashMap<String,String>>(); for(int i=0;i<10;i++){ HashMap<String, String> hm = new HashMap<String,String>(); hm.put(COUNTRY, mCountries[i]); hm.put(COUNT, mCount[i]); hm.put(FLAG, Integer.toString(mFlags[i]) ); mList.add(hm); } // Keys used in Hashmap String[] from = { FLAG,COUNTRY,COUNT }; // Ids of views in listview_layout int[] to = { R.id.flag , R.id.country , R.id.count}; // Instantiating an adapter to store each items // R.layout.drawer_layout defines the layout of each item mAdapter = new SimpleAdapter(this, mList, R.layout.drawer_layout, from, to); // Getting reference to DrawerLayout mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout); // Creating a ToggleButton for NavigationDrawer with drawer event listener mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer , R.string.drawer_open,R.string.drawer_close){ /** Called when drawer is closed */ public void onDrawerClosed(View view) { highlightSelectedCountry(); supportInvalidateOptionsMenu(); } /** Called when a drawer is opened */ public void onDrawerOpened(View drawerView) { getSupportActionBar().setTitle("Select a Country"); supportInvalidateOptionsMenu(); } }; // Setting event listener for the drawer mDrawerLayout.setDrawerListener(mDrawerToggle); // ItemClick event handler for the drawer items mDrawerList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { // Increment hit count of the drawer list item incrementHitCount(position); if(position < 5) { // Show fragment for countries : 0 to 4 showFragment(position); }else{ // Show message box for countries : 5 to 9 Toast.makeText(getApplicationContext(), mCountries[position], Toast.LENGTH_LONG).show(); } // Closing the drawer mDrawerLayout.closeDrawer(mDrawer); } }); // Enabling Up navigation getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayShowHomeEnabled(true); // Setting the adapter to the listView mDrawerList.setAdapter(mAdapter); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); mDrawerToggle.syncState(); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void incrementHitCount(int position){ HashMap<String, String> item = mList.get(position); String count = item.get(COUNT); item.remove(COUNT); if(count.equals("")){ count = " 1 "; }else{ int cnt = Integer.parseInt(count.trim()); cnt ++; count = " " + cnt + " "; } item.put(COUNT, count); mAdapter.notifyDataSetChanged(); } public void showFragment(int position){ //Currently selected country mTitle = mCountries[position]; // Creating a fragment object CountryFragment cFragment = new CountryFragment(); // Creating a Bundle object Bundle data = new Bundle(); // Setting the index of the currently selected item of mDrawerList data.putInt("position", position); // Setting the position to the fragment cFragment.setArguments(data); // Getting reference to the FragmentManager FragmentManager fragmentManager = getSupportFragmentManager(); // Creating a fragment transaction FragmentTransaction ft = fragmentManager.beginTransaction(); // Adding a fragment to the fragment transaction ft.replace(R.id.content_frame, cFragment); // Committing the transaction ft.commit(); } // Highlight the selected country : 0 to 4 public void highlightSelectedCountry(){ int selectedItem = mDrawerList.getCheckedItemPosition(); if(selectedItem > 4) mDrawerList.setItemChecked(mPosition, true); else mPosition = selectedItem; if(mPosition!=-1) getSupportActionBar().setTitle(mCountries[mPosition]); } }
15. Update the file AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="in.wptrafficanalyzer.navigationdrawerlegacy" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.AppCompat.Light" > <activity android:name="in.wptrafficanalyzer.navigationdrawerlegacy.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> </application> </manifest>
16. Screenshot of the application
17. Download Source Code

I am George Mathew, working as software architect and Android app developer at wptrafficanalyzer.in
You can hire me on hourly basis or on project basis for Android applications development.
For hiring me, please mail your requirements to info@wptrafficanalyzer.in.
My other blogs
store4js.blogspot.com