Implementing ActionBarSherlock Side Menu Navigation with Fragment Tabs Tutorial

In this tutorial, you will learn how to implement ActionBarSherlock Side Menu Navigation with fragment tabs in your Android application. The navigation drawer is a panel that transitions in from the left edge of the screen and displays the main navigation options. Using a Side Menu Navigation Drawer allows the user to easily navigate between fragments or activities. The navigation drawer can be brought onto the screen by swiping from the left edge of the screen or by touching the application icon on the action bar. We will create a custom side menu navigation drawer using ActionBarSherlock Library and on selected menu item click will show a fragment and a fragment with Tabs. So lets begin…

Download the Latest Support Library

Download the latest support library revision 13 that supports the new Navigation Drawer. 

Link : http://developer.android.com/tools/extras/support-library.html

Replace the old support library (android-support-v4.jar) with the new support library in your ActionBarSherlock Library.

Support Package, revision 13 (May 2013)

Changes for v4 support library:
  • Added DrawerLayout for creating a Navigation Drawer that can be pulled in from the edge of a window.

Prepare your project by importing the ActionBarSherlock Library. Refer to Implementing ActionBarSherlock in Android tutorial.

Create a new project in Eclipse File > New > Android Application Project. Fill in the details and name your project SideMenuTabsTutorial.

Application Name : SideMenuTabsTutorial

Project Name : SideMenuTabsTutorial

Package Name : com.androidbegin.sidemenutabstutorial

Open your MainActivity.java and paste the following code.

MainActivity.java

package com.androidbegin.sidemenutabstutorial;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.Fragment;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.support.v4.view.GravityCompat;

public class MainActivity extends SherlockFragmentActivity {

	// Declare Variable
	DrawerLayout mDrawerLayout;
	ListView mDrawerList;
	ActionBarDrawerToggle mDrawerToggle;
	MenuListAdapter mMenuAdapter;
	String[] title;
	String[] subtitle;
	int[] icon;
	Fragment fragment1 = new Fragment1();
	Fragment fragment2 = new Fragment2();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.drawer_main);

		// Generate title
		title = new String[] { "Title Fragment 1", "Title Fragment 2"};

		// Generate subtitle
		subtitle = new String[] { "Subtitle Fragment 1", "Subtitle Fragment 2"};

		// Generate icon
		icon = new int[] { R.drawable.action_about, R.drawable.action_settings};

		// Locate DrawerLayout in drawer_main.xml
		mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

		// Locate ListView in drawer_main.xml
		mDrawerList = (ListView) findViewById(R.id.left_drawer);

		// Set a custom shadow that overlays the main content when the drawer
		// opens
		mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
				GravityCompat.START);

		// Pass results to MenuListAdapter Class
		mMenuAdapter = new MenuListAdapter(this, title, subtitle, icon);

		// Set the MenuListAdapter to the ListView
		mDrawerList.setAdapter(mMenuAdapter);

		// Capture button clicks on side menu
		mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

		// Enable ActionBar app icon to behave as action to toggle nav drawer
		getSupportActionBar().setHomeButtonEnabled(true);
		getSupportActionBar().setDisplayHomeAsUpEnabled(true);

		// ActionBarDrawerToggle ties together the the proper interactions
		// between the sliding drawer and the action bar app icon
		mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
				R.drawable.ic_drawer, R.string.drawer_open,
				R.string.drawer_close) {

			public void onDrawerClosed(View view) {
				// TODO Auto-generated method stub
				super.onDrawerClosed(view);
			}

			public void onDrawerOpened(View drawerView) {
				// TODO Auto-generated method stub
				super.onDrawerOpened(drawerView);
			}
		};

		mDrawerLayout.setDrawerListener(mDrawerToggle);

		if (savedInstanceState == null) {
			selectItem(0);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getSupportMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		if (item.getItemId() == android.R.id.home) {

			if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
				mDrawerLayout.closeDrawer(mDrawerList);
			} else {
				mDrawerLayout.openDrawer(mDrawerList);
			}
		}

		return super.onOptionsItemSelected(item);
	}

	// The click listener for ListView in the navigation drawer
	private class DrawerItemClickListener implements
			ListView.OnItemClickListener {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			selectItem(position);
		}
	}

	private void selectItem(int position) {

		FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
		// Locate Position
		switch (position) {
		case 0:
			ft.replace(R.id.content_frame, fragment1);
			break;
		case 1:
			ft.replace(R.id.content_frame, fragment2);
			break;
		}
		ft.commit();
		mDrawerList.setItemChecked(position, true);
		// Close drawer
		mDrawerLayout.closeDrawer(mDrawerList);
	}

	@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 toggles
		mDrawerToggle.onConfigurationChanged(newConfig);
	}
}

In this activity, we have created some sample titles, subtitles and icons into a string and integer arrays and passed it into MenuListAdapter to display it on a listview as a side menu. On listview side menu click will display the selected fragment together with the title on the action bar. The ActionBarDrawerToggle facilitates the proper interaction behavior between the action bar icon and the navigation drawer.

We have prepared some sample icons for this tutorial. Insert your downloaded sample icons into your res > drawable-hdpi.

Sample Icons

[wpfilebase tag=file id=49 tpl=download-button /]

Next, create an XML graphical layout for your navigation drawer. Go to res > layout > Right Click on layout > New > Android XML File

Name your new XML file drawer_main.xml and paste the following code.

drawer_main.xml

<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" >

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#111"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp" />

</android.support.v4.widget.DrawerLayout>

Next, create a custom menu adapter class. Go to File > New > Class and name it MenuListAdapter.java. Select your package named com.androidbegin.sidemenutabstutorial and click Finish.

Open your MenuListAdapter.java and paste the following code.

MenuListAdapter.java

package com.androidbegin.sidemenutabstutorial;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MenuListAdapter extends BaseAdapter {

	// Declare Variables
	Context context;
	String[] mTitle;
	String[] mSubTitle;
	int[] mIcon;
	LayoutInflater inflater;

	public MenuListAdapter(Context context, String[] title, String[] subtitle,
			int[] icon) {
		this.context = context;
		this.mTitle = title;
		this.mSubTitle = subtitle;
		this.mIcon = icon;
	}

	@Override
	public int getCount() {
		return mTitle.length;
	}

	@Override
	public Object getItem(int position) {
		return mTitle[position];
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		// Declare Variables
		TextView txtTitle;
		TextView txtSubTitle;
		ImageView imgIcon;

		inflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View itemView = inflater.inflate(R.layout.drawer_list_item, parent,
				false);

		// Locate the TextViews in drawer_list_item.xml
		txtTitle = (TextView) itemView.findViewById(R.id.title);
		txtSubTitle = (TextView) itemView.findViewById(R.id.subtitle);

		// Locate the ImageView in drawer_list_item.xml
		imgIcon = (ImageView) itemView.findViewById(R.id.icon);

		// Set the results into TextViews
		txtTitle.setText(mTitle[position]);
		txtSubTitle.setText(mSubTitle[position]);

		// Set the results into ImageView
		imgIcon.setImageResource(mIcon[position]);

		return itemView;
	}

}

In this custom menu adapter class, string and integer arrays are set into the TextViews and ImageViews followed by the positions.

Next, create an XML graphical layout for the listview menu item. Go to res > layout > Right Click on layout > New > Android XML File

Name your new XML file drawer_list_item.xml and paste the following code.

drawer_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="?attr/spinnerDropDownItemStyle"
    android:layout_width="match_parent"
    android:layout_height="?attr/dropdownListPreferredItemHeight"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:adjustViewBounds="true" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical|left"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/title"
            style="?attr/spinnerDropDownItemStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:singleLine="true" />

        <TextView
            android:id="@+id/subtitle"
            style="?attr/spinnerDropDownItemStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:singleLine="true"
            android:textAppearance="?attr/textAppearanceSmall" />
    </LinearLayout>

</LinearLayout>

Next, create the first fragment. Go to File > New > Class and name it Fragments1.java. Select your package named com.androidbegin.sidemenutabstutorial and click Finish.

Open your Fragments1.java and paste the following code.

Fragments1.java

package com.androidbegin.sidemenutabstutorial;

import java.lang.reflect.Field;

import com.actionbarsherlock.app.SherlockFragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment1 extends SherlockFragment {
	// Declare Variable
	private FragmentTabHost mTabHost;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// Create FragmentTabHost
		mTabHost = new FragmentTabHost(getSherlockActivity());
		// Locate fragment1.xml to create FragmentTabHost
		mTabHost.setup(getSherlockActivity(), getChildFragmentManager(), R.layout.fragment1);
		// Create Tab 1
		mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("Tab 1"), FragmentTab1.class, null);
		// Create Tab 2
		mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("Tab 2"), FragmentTab2.class, null);

		return mTabHost;
	}

	// Detach FragmentTabHost
	@Override
	public void onDetach() {
		super.onDetach();

		try {
			Field childFragmentManager = Fragment.class
					.getDeclaredField("mChildFragmentManager");
			childFragmentManager.setAccessible(true);
			childFragmentManager.set(this, null);

		} catch (NoSuchFieldException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}
	// Remove FragmentTabHost 
	@Override
	public void onDestroyView() {
		super.onDestroyView();
		mTabHost = null;
	}

}

In this Fragment1, we have created two tabs that contains fragment using FragmentTabHost. To understand more about FragmentTabHost visit Android Docs here.

Next, create an XML graphical layout for first fragment. Go to res > layout > Right Click on layout > New > Android XML File

Name your new XML file fragment1.xml and paste the following code.

fragment1.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

</RelativeLayout>

Next, create the second fragment. Go to File > New > Class and name it Fragments2.java. Select your package named com.androidbegin.sidemenutabstutorial and click Finish.

Open your Fragments2.java and paste the following code.

Fragments2.java

package com.androidbegin.sidemenutabstutorial;

import java.lang.reflect.Field;

import com.actionbarsherlock.app.SherlockFragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTabHost;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment2 extends SherlockFragment {
	// Declare Variable
	private FragmentTabHost mTabHost;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// Create FragmentTabHost
		mTabHost = new FragmentTabHost(getSherlockActivity());
		// Locate fragment2.xml to create FragmentTabHost
		mTabHost.setup(getSherlockActivity(), getChildFragmentManager(), R.layout.fragment2);
		// Create Tab 3
		mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("Tab 3"), FragmentTab3.class, null);
		// Create Tab 4
		mTabHost.addTab(mTabHost.newTabSpec("tab4").setIndicator("Tab 4"), FragmentTab4.class, null);

		return mTabHost;
	}

	// Detach FragmentTabHost
	@Override
	public void onDetach() {
		super.onDetach();

		try {
			Field childFragmentManager = Fragment.class
					.getDeclaredField("mChildFragmentManager");
			childFragmentManager.setAccessible(true);
			childFragmentManager.set(this, null);

		} catch (NoSuchFieldException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}
	// Remove FragmentTabHost 
	@Override
	public void onDestroyView() {
		super.onDestroyView();
		mTabHost = null;
	}

}

In this Fragment2, we have created two tabs that contains fragment using FragmentTabHost.

Next, create an XML graphical layout for second fragment. Go to res > layout > Right Click on layout > New > Android XML File

Name your new XML file fragment2.xml and paste the following code.

fragment2.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

</RelativeLayout>

Next, create the first fragment tab. Go to File > New > Class and name it FragmentTab1.java. Select your package named com.androidbegin.sidemenutabstutorial and click Finish.

Open your FragmentTab1.java and paste the following code.

FragmentTab1.java

package com.androidbegin.sidemenutabstutorial;

import com.actionbarsherlock.app.SherlockFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentTab1 extends SherlockFragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fragmenttab1, container, false);
		return rootView;
	}

}

Next, create the second fragment tab. Go to File > New > Class and name it FragmentTab2.java. Select your package named com.androidbegin.sidemenutabstutorial and click Finish.

Open your FragmentTab2.java and paste the following code.

FragmentTab2.java

package com.androidbegin.sidemenutabstutorial;

import com.actionbarsherlock.app.SherlockFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentTab2 extends SherlockFragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fragmenttab2, container, false);
		return rootView;
	}

}

Next, create the third fragment tab. Go to File > New > Class and name it FragmentTab3.java. Select your package named com.androidbegin.sidemenutabstutorial and click Finish.

Open your FragmentTab3.java and paste the following code.

FragmentTab3.java

package com.androidbegin.sidemenutabstutorial;

import com.actionbarsherlock.app.SherlockFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentTab3 extends SherlockFragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fragmenttab3, container, false);
		return rootView;
	}

}

Next, create the forth fragment tab. Go to File > New > Class and name it FragmentTab4.java. Select your package named com.androidbegin.sidemenutabstutorial and click Finish.

Open your FragmentTab4.java and paste the following code.

FragmentTab4.java

package com.androidbegin.sidemenutabstutorial;

import com.actionbarsherlock.app.SherlockFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentTab4 extends SherlockFragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fragmenttab4, container,
				false);
		return rootView;
	}

}

Next, create an XML graphical layout for first fragment tab. Go to res > layout > Right Click on layout > New > Android XML File

Name your new XML file fragmenttab1.xml and paste the following code.

fragmenttab1.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/FragmentTab1" />

</RelativeLayout>

Next, create an XML graphical layout for second fragment tab. Go to res > layout > Right Click on layout > New > Android XML File

Name your new XML file fragmenttab2.xml and paste the following code.

fragmenttab2.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/FragmentTab2" />

</RelativeLayout>

Next, create an XML graphical layout for third fragment tab. Go to res > layout > Right Click on layout > New > Android XML File

Name your new XML file fragmenttab3.xml and paste the following code.

fragmenttab3.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/FragmentTab3" />

</RelativeLayout>

Next, create an XML graphical layout for forth fragment tab. Go to res > layout > Right Click on layout > New > Android XML File

Name your new XML file fragmenttab4.xml and paste the following code.

fragmenttab4.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/FragmentTab4" />

</RelativeLayout>

Next, change the application name and texts. Open your strings.xml in your res > values folder and paste the following code.

strings.xml

<resources>

    <string name="app_name">Side Menu Tabs Tutorial</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_main">Side Menu Tabs Tutorial</string>
    <string name="drawer_open">Open navigation drawer</string>
    <string name="drawer_close">Close navigation drawer</string>
    <string name="FragmentTab1">This is Fragment Tab 1</string>
    <string name="FragmentTab2">This is Fragment Tab 2</string>
    <string name="FragmentTab3">This is Fragment Tab 3</string>
    <string name="FragmentTab4">This is Fragment Tab 4</string>

</resources>

In your AndroidManifest.xml, we need to change the theme style to “Theme.Sherlock” and set your preferable Android minimum SDK version. Open your AndroidManifest.xml and paste the following code.

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.androidbegin.sidemenutabstutorial"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.Sherlock" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

Output:

Side Menu Tabs Tutorial Screenshot

Source Code

[purchase_link id=”7979″ text=”Purchase to Download Source Code” style=”button” color=”green”]

Latest comments

can i use same application in dropdown in action bar.... i need...when i click on dropdown it gives some items ...when i click on that item it goes to tabs....if i click any other item in dropdown it goes to different tabs.....

ranapratap

Implementing ActionBarSherlock Side Menu Navigation with Fragment Tabs Tutorial

hi can you tell me how i can use the onbackpressed method in FragmentTab1 i tried thanx you

Ibrahim Ahmed Alshareif

Implementing ActionBarSherlock Side Menu Navigation with Fragment Tabs Tutorial

Now how to create a list view in those tabs?? Please help me

HARSHAVARDHAN

Implementing ActionBarSherlock Side Menu Navigation with Fragment Tabs Tutorial

Please, how can i add a mapview inside a fragment tab ? I always got this error " Duplicate id 0x7f050039, tag map, or parent id 0x0 with another fragment for com.google.android.gms.maps.SupportMapFragment" Thanks

Hammer

Implementing ActionBarSherlock Side Menu Navigation with Fragment Tabs Tutorial