Quantcast
Channel: Knowledge by Experience » Android
Viewing all articles
Browse latest Browse all 23

Android Sidebar Navigation Drawer with Icons

$
0
0

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

Link this project to ActionBarCompat library ( V7)

Figure 1 : Link this project to ActionBarCompat library ( V7)


5. Download and extract the icon images to the directory res/drawable-mdpi

Icon Images


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

Sidebar Navigation Drawer Demo

Figure 2 : Sidebar Navigation Drawer Demo


17. Download Source Code


How to hire me?

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



Viewing all articles
Browse latest Browse all 23

Latest Images

Trending Articles



Latest Images