Tab Layout in Android with ActionBar and Fragment

In a previous post I wrote an example of Layout Tab using a TabActivity class that it is deprecated since version 3.0 Honeycomb of Android.
In this post I develop the same interface using ActionBar and Fragment, and I tried wherever possible to limit the changes to the files *.xml.

  1. create an Android project called TabActionBar, a package eu.lucazanini and an activity
  2. edit the file AndroidManifest.xml, it should be the default one
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android=""
        android:versionName="1.0" >
        <uses-sdk android:minSdkVersion="15" />
            android:label="@string/app_name" >
                android:label="@string/app_name" >
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
  3. edit the file /res/values/strings.xml, to manage the labels
    <?xml version="1.0" encoding="utf-8"?>
        <string name="app_name">TabActionBar</string>
        <string name="label1">one</string>
        <string name="label2">two</string>
        <string name="body1"> body one</string>
        <string name="body2">body two</string>
  4. edit the file res/layout/main.xml, it should be the default one (this file is not used, so you can skip this step, see the comments below)
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android=""
        android:orientation="vertical" >
  5. create the files res/layout/tab1.xml and res/layout/tab2.xml, representing the contents of 2 tabs
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android=""
            android:text="@string/body1" />
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android=""
            android:text="@string/body2" />
  6. edit the class, note that the labels of the tabs will be capitalized and that eventually you can put an icon or a view with the methods setIcon or setCustomView
    package eu.lucazanini;
    import android.os.Bundle;
    public class TabActionBarActivity extends Activity {
    	public void onCreate(Bundle savedInstanceState) {
    		ActionBar actionBar = getActionBar();
    		String label1 = getResources().getString(R.string.label1);
    		Tab tab = actionBar.newTab();
    		TabListener<Tab1Fragment> tl = new TabListener<Tab1Fragment>(this,
    				label1, Tab1Fragment.class);
    		String label2 = getResources().getString(R.string.label2);
    		tab = actionBar.newTab();
    		TabListener<Tab2Fragment> tl2 = new TabListener<Tab2Fragment>(this,
    				label2, Tab2Fragment.class);
    	private class TabListener<T extends Fragment> implements
    			ActionBar.TabListener {
    		private Fragment mFragment;
    		private final Activity mActivity;
    		private final String mTag;
    		private final Class<T> mClass;
    		 * Constructor used each time a new tab is created.
    		 * @param activity
    		 *            The host Activity, used to instantiate the fragment
    		 * @param tag
    		 *            The identifier tag for the fragment
    		 * @param clz
    		 *            The fragment's Class, used to instantiate the fragment
    		public TabListener(Activity activity, String tag, Class<T> clz) {
    			mActivity = activity;
    			mTag = tag;
    			mClass = clz;
    		public void onTabSelected(Tab tab, FragmentTransaction ft) {
    			// Check if the fragment is already initialized
    			if (mFragment == null) {
    				// If not, instantiate and add it to the activity
    				mFragment = Fragment.instantiate(mActivity, mClass.getName());
    				ft.add(, mFragment, mTag);
    			} else {
    				// If it exists, simply attach it in order to show it
    		public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    			if (mFragment != null) {
    				// Detach the fragment, because another one is being attached
    		public void onTabReselected(Tab tab, FragmentTransaction ft) {
    			// User selected the already selected tab. Usually do nothing.
  7. create the classes and
    package eu.lucazanini;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.LinearLayout;
    public class Tab1Fragment extends Fragment {
    	public View onCreateView(LayoutInflater inflater, ViewGroup container,
    			Bundle savedInstanceState) {
    		return (LinearLayout) inflater.inflate(R.layout.tab1, container, false);
    package eu.lucazanini;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.LinearLayout;
    public class Tab2Fragment extends Fragment {
    	public View onCreateView(LayoutInflater inflater, ViewGroup container,
    			Bundle savedInstanceState) {
    		return (LinearLayout) inflater.inflate(R.layout.tab2, container, false);
  8. launch the app

115 replies on “Tab Layout in Android with ActionBar and Fragment”

Dear Team,
I made same tab layout pages with action bar..Now i want to choose images or files or capture image via camera but startactivity lost…not call.

Error !!!!!
Unable to start activity ComponentInfo{com.Resto.menuresto/com.Resto.menuresto.AcceuilActivity}: java.lang.NullPointerException: Attempt to invoke virtual method ‘void’ on a null object reference
help me ?

Hi Luca,
tutorial looks OK.
Although 2 questions:
1. How to make tabs not occupying full screen width? Like just one/two tabs on the left/right side.
2. How to adjust tab width according to the length of the label?

altra domanda se posso,
come potrei aggiungere lo scrolling orizzontale fra le tab? quindi senza dover premere il tasto dell’action bar, ma cambiando le tab con un semplice swipe?


ciao Luca,
grazie per l’ottimo tutorial!
se io ho un TextView chiamato tv1 nell’xml di un tab, per esempio tab1, se dal file TabActionBarActivity volessi modificare il contenuto di quel text view (perchè reperisco delle informazioni da un database)
se provo a fare
tv = (TextView) findViewById(;

ottengo nullPointerException

I put a button in Tab1Fragment and on clicking it I want to replace Tab1Fragment with Tab3Fragment. How can I do this?

Thank you for yur tutorial.
I woould like to use a button to do some actions in your example but it doesn’t work when i click on it.
Do you have an example with button inside tab ?
tank you for your help.

If you add a button to the content below the tabs you can follow this.
If you want to add the buttons in place of the labels of tabs I am not sure, you can see this and try to add the buttons in the xml layout files.

How to change the layout of the actionbar tabs itself upon changing the state of the tabs, means the layout of the tab should change if it is selected from unselected state. I tried setCustomView() from within my TabListener methods, but that does not seem to work.

Ciao Luca,
volevo chiederti una cosa:
ho seguito l’esempio “Adding Navigation Tabs” alla pagina:
Il tutto funziona perfettamente.
IL problema sta nel cambiare il contenuto (quindi fragment) sotto un tab.
Ad esempio ho messo nel fragment caricato sotto il tab_1 un bottone.
vorrei che quando si preme il bottone venga caricato un altro fragment sempre nello stesso tab.
In rete si trovano tutti esempi che mostrano il caricamente dei tab inizali con i ripsettivi content, ma non riesco a cambiare po il contenuto…
grazie mille 🙂


If we run this code in 10′ tab, the tabs don’t fill full actionbar…

I want that tabs should fill whole actionbar.

Grazie per il tutorial,
Ho seguito tutti i passi ma il menu lo mette sulla stessa riga dove cè il logo e il nome della app.

Se il titolo e il logo sono assenti è come se tu avessi il codice:


Se invece sono presenti, è la situazione in cui la larghezza del dispositivo è sufficientemente ampia per inserire titolo, logo e tabs in una sola riga, spesso in modalità landscape.

Hi Luca,

great tutorial.
All fine, but when I use the app and I select another tab the text overlaps the first one.
I don’ understand why. Could you give any suggestion?



I am using the same example as above in my app too. But I am implementing it a little different way.

In one of the tabs(Search), when user clicks a button, I replace the current fragment with another fragment using

When user clicks button on the new fragment, a new fragment replaces the existing fragment.

Due to this when I click on another tab and click on the Search Tab, the latest fragment is shown but when I click on back button, I get a Blank page.

The reason for this is ft.attach() recreates the view according to the documentation.

Is there a way to preserve the view hierarchy when switching to another tab?

FragmentTransaction has the show and hide methods too, so if the fragment is already attached you can try to use them.
You can catch the back button with:

public boolean onKeyDown(int keyCode, KeyEvent event) {
  if (event.getAction() == KeyEvent.ACTION_DOWN) {
    switch (keyCode) {
    case KeyEvent.KEYCODE_BACK:
// ...

or overriding onBackPressed method.

I can do that. But I am not sure how to do that.
Let me explain with example.
Tab 1 -> Fragment a -> fragment b -> Fragment c
Tab 2-> Fragment d

I click on Tab 1, go from a to b to c. When I stay on Tab 1, and I am in ‘a’, clicking back goes to b, clicking back in b goes to ‘a’

But when I am in Fragent ‘c’. and click on Tab 2 and come back to Tab 1 and click back, I get blank.

Can you give example on what I should put in those methods? And is onBackPressed() activity method?

One more question. When constructing the tablistener, we give a fragment as constructor. Is it possible to change the fragment associated with the tablistener later?

you haven’t used setContentView(view) in then what’s the use of main.xml?
and can we navigate through these tabs using swap gesture ?

Hey Luca,

thanks for the tutorial. Your app runs fine for me as well, however I am struggeling with the layout of the tab widgets. So if I run the app it looks different compared to your screenshots.
1. I do not have the upper blue border above the tab widgets.
2. My tab widgets do not fill the whole screen horizontally. Tab1 starts not at the left edge of the screen and tab2 does not end at the right edge of the screen.
The same happens for my app which I build according to adroids tutorial
It is like there is a default max width for the tab widgets.

You can’t create an action bar in the middle of the screen.
In order to have tabs in the middle of the screen you must create a custom layout.

You can’t replace fragment with activities in this example.
You can call an activity from an other activity using the startActivity method and every activity has its own actionbar.


Your tutorial is great. But is it possible to customize my own tabs using fragmentactivity. I’m having difficulties in converting my current TabActvitiy into using FragmentActivity.

In my tutorial I use, in FragmentActivity you have to use
Then you can’t start from my example if you use FragmentActivity.

on running this code i am getting an error “R cannot be resolved as a variable”
what should i do?

Remove every import *.R.*
Check Java Build Path of your project
Clean and Build your Project

Thanks for your insight on this topic!!! I have one question: Why is it when I rotate my phone and select another tab the previous tab remains onscreen with the selected tab?

Thanks for the awesome tutorial !!!

When I run this tutorial in as standalone project it works fine but I have a Main activity and I want to launch tabbed activity on button click from Main activity. If I just click the button to launch this tabbed activity then it crashed.

Button drinkListBtn = (Button) findViewById(;
drinkListBtn.setOnClickListener(new OnClickListener() {

public void onClick(View v) {
startActivity(new Intent(Main.this, TabbedActivity.class));


Logcat is some what like this.
05-02 16:43:42.309: W/dalvikvm(4337): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
05-02 16:43:42.339: E/AndroidRuntime(4337): FATAL EXCEPTION: main
05-02 16:43:42.339: E/AndroidRuntime(4337): java.lang.RuntimeException: Unable to start activity ComponentInfo

Any help, Thanks


This is very nice tutorial. I had implemented this tutorial. But I am getting java.lang.NullPointerException
at statement actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS). So will you please
help me to resolve this.


actionBar seems null.
actionBar is assigned at the row before:
ActionBar actionBar = getActionBar();

I dont’t know why but you can check AndroidManifest.xml, especially the minSdkVersion value.

Hello Luca,
Thanks for this tutorial, it was very helpful. One possibly more advanced question though, sorry if you’ve already covered this somewhere else.
If you had 2 Fragments under one tab (for example Tab1Fragment1 and Tab1Fragment2) and Tab1Fragment1 was added when the tab was created. If you navigate to Tab1Fragment2, then change orientation, this would reload the Activity and call onCreate which would add Tab1Fragment1 again. How would I stop the ActionBar using the Tab1Fragment1 and use Tab1Fragment2 instead? Would I need to re-add the second Fragment later or how would I attach it again?
Thanks for any help you can give me, Ben

Maybe android:configChanges=”orientation|screenSize” in AndroidManifest.xml is what you want.
You can find more info here.

Hello Luca,

By clicking on the tabs the methods onCreateView and onActivityCreated are always initiated, it is possible to save the state of the Fragment to the screen not recreated?

Replace ft.attach(mFragment); with; and ft.detach(mFragment); with ft.hide(mFragment);
If you want to save the state of the fragment consider to override the onSaveInstanceState method.


The my problem the is following, when using the TabActivity to navigate between tabs Activity, when changing tabs starts the onCreate once every Activity, but always passes by onResume, in the Android version 4 is informed that this deprecated TabActivity , so the only way would be to use the ActionBar navigation and to convert my in Fragment Activity? Or is it possible to navigate between Activity in ActionBar or otherwise in another way in Android 4?
Regarding the first case,modify Activity for Fragment, always change the tabs the interface and rebuilt in Fragment and passes through the methods onCreateView and onActivityCreated, however needed that behaves coforme navigation between Activity, and only go through onResume.

In ActionBar navigation you must use Fragments and not Activities.
As I say before, if you replace

ft.attach(mFragment); with;
ft.detach(mFragment); with ft.hide(mFragment);

the onCreateView and onActivityCreated methods are not called.

Hi Luca!! It’s a wonderful tutorial thanks for that.i had a question like how to add picture(image) on the each tab instead of “one” “two”.


I believe this is a good tutorial but I can`t seem to get the positioning right.
The tab widget is displayed on the rigth side of the app name and all I can see is the tab “One”.
I can see the tab content “Tab one”.
I can`t see what you show when you launch the app.
I launch it through a virtual device.

First off thanks a lot for the good tutorial.

I’m running into a problem,
TabListener a = new TabListener(this, getString(R.string.title_new), New_tab.class);

give me an error: Bound mismatch: The type New_tab is not a valid substitute for the bounded parameter of the type Main.TabListener

any ideas?

thanks, for anyone else who runs into the problem, more specifically it was changing import; to import;


Excellent tutorial Luca!! I have a question regarding Fragments.

This is how i create my tabs

ActionBar actionBar = getActionBar();

Tab tabA = actionBar.newTab();
actionBar.addTab(tabA); //same for the other tabs

Then i implement the ActionBar.TabListener

public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
Fragment fragment = null ;

if (tab.getPosition() == 0){
fragment = new TabAFragment();

}//initialise all Tab Fargments
if (fragment != null){
FragmentTransaction transaction = getFragmentManager().beginTransaction();
//container is a framelayout in the main_activity layout
transaction.replace(, fragment);
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {

Say TabAFragment has a Button and i want to display the contents of the resulting layout within TabAFragment layout, am i right to do this
………. //some declaration missing
fragment = new TabAButtonFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(, fragment);


Hi Luca,
First of all, thanxs so much for this tutorial because I’ve been looking for days trying to find something like this and it was just impossible.
I want to ask you how to personalize the tabs like getting them at the bottom, changing color, etc…


Hi Luca, thank you for this great tutorial! This is the only one that I have tried that worked flawlessly. I want to add a WebView to one of the tab layouts (tab2.xml) to display a website but I get a NullPointerException when I try to load the URL. Any suggestions on how to properly add a WebView to a tab layout? Thanks 🙂

Add the WebView to a layout, for example tab2.xml
Replace the onCreateView event with:

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
	    Bundle savedInstanceState) {
	LinearLayout ll = (LinearLayout) inflater.inflate(R.layout.tab2,
		container, false);
	webView = (WebView) ll.findViewById(;

	return ll;

This code requires

private WebView webView;

Remember to add the permission

<uses-permission android:name="android.permission.INTERNET"/>

in your AndroidManifest.xml

This is awesome. Thanks Luca! One last thing, do you have any idea on how to save the state of the WebView? I mean, the webview refreshes everytime I tap on the tab. Thanks again =)

Best tutorial out there! Thank you! This is the only thing on the web that works for me! Straightforward and simple! good stuff!

Hi, usefull tutorial !

Now i manbage to have multiple layouit loaded into tabs =)

But as a beginner, i wonder how to access the controls in my tab1 and tab2 fragment class.

How can i set onClickListeners in theses controls ? (eg on textview1)


You can replace onCreateView in

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
	    Bundle savedInstanceState) {
	LinearLayout ll = (LinearLayout) inflater.inflate(R.layout.tab1,
		container, false);

	TextView tv = (TextView) ll.findViewById(;
	tv.setOnClickListener(new OnClickListener() {
	    public void onClick(View v) {
		// your code goes here
		Toast t = Toast.makeText(getActivity(), "bye",

	return ll;

Otherwise you can implement OnClickListener in the class Tab1Fragment.


I have 2 tabs, one of them contains very long text so I put a TextView inside ScrollView in one of the fragment.
Now I scroll down in the tab, select other tab and again select the first tab, I always get my scroll positioned on top.
I want it to be at same position where user leaves it even after changing tabs.
Am I missing something in this code? or I have to workout something else?


i have tried the example. i found that if i use tab1 now, then press home button and turn to setting to set the language to another one, tab1 would be created twice when the activity launched again. If you can help me that would be great.

Hello Luca, I have recreated your tutorial I think faithfully but notwithstanding I have 4 errors that won’t allow launch.

The errors are essentially the same in the .java class files using getResources the IDE claims the strings.xml file symbol variables cannot be found?

This is in spite of the fact that the R file contains the IDs for label1, label2, tab1 and tab2.

Any suggestions as to why these errors?

Please advise, David.

Check the file res/values/strings.xml
Are you sure you are not getting the resources inside a static class or method?
The inner class TabListener must not be static.

Hello Luca , Iam getting same error in this tutorial .java file is not able to find R.string.label1 same is case with other resources.

Check there are not any import android.R in the java files.
Under Project menu in eclipse, uncheck build automatically, clean and build project.

you have got us to remove this line from the res/values/strings.xml:

<string name="action_settings">Settings</string>

Hello, the tutorial is just great. Congratulations!
I have a doubt that maybe you can solve.
Let’s say that I have my own View for the layout which only shows “this is the TAB x” where x is 1 or 2 depending on which tab are we. How could you do that? Sending an Inten looks the normal option but from where and how?
If you can help me that would be great.

I am not sure to understand what you mean.
The 2 fragment classes can have the same layout resource and you can set a textview in it.

Se in Tab1Fragment ho un button come faccio a sostituire il fragment attuale con uno nuovo?
La sostituzione dovrebbe avvenire a seguito dell’onClick() sul button nel fragment 1 e non su un icon dell’action bar…come ad esempio nelle app Android di Instagram o Twitter.

Penso che nell’evento click del button ci dovrebbe essere qualcosa come:
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();

E’ quello che sto utilizzando anche io ma ho un dubbio sul replace…Ho creato la mia Action Bar seguendo la documentazione ufficiale di Android ed ho visto che coincide con il suo codice ovvero un’activity iniziale in cui viene creata la Bar con le sue tab (fragment). I fragment, quindi, si sostituiscono sempre sulla stessa Activity perchè non ve ne sono altre.
Nel caso della mia domanda, dunque, la FragmentTransaction deve sostituire a Tab1Fragment un NuovoFragment sempre nell’activity di partenza e quindi nella replace() ho indicato come secondo parametro il nuovo fragment ma come primo?
Ho utilizzato in altri progetti i Fragment e le FragmentTransaction ma sempre utilizzando un’activity per ogni Fragment e sostituendoli con gli xml.

Grazie per la risposta.

Il primo parametro è l’id del container in cui sostituire il fragment.
In questo post l’id del container non è stato definito esplicitamente in un file .xml di layout quindi penso che si dovrebbe usare quello di default:

Si, così ho visto che funziona la sostituzione del fragment ma viene ”sconvolto” il funzionamento della Bar.
Mi spiego meglio. Nel momento in cui, a seguito dell’OnClick, viene eseguita la FragmentTransaction con il nuovo fragment (lo chiamo N per comodità), se si cambia tab dall’ActionBar, quest’ultimo viene sovrapposto ad N e non sostituito, quindi, continuo a visualizzare il contenuto del fragment N (ad esempio una TextView = Nuovo) con sopra il contenuto del tab selezionato dalla Bar (ad esempio una TextView = Tab x).

Sospettavo che si potesse verificare una situazione di questo tipo, probabilmente si deve modificare la classe interna che gestisce le tab (TabListener) e usare il metodo detach di FragmentTransaction per rimuovere il frammento “N” quando non deve essere più visibile.

Intende all’interno del metodo onTabSelected() così che ogni volta che si deve usare il metodo attach() per aggiungere un tab dell’ActionBar si rimuova prima il fragment eventualmente presente?

Si, direi che quello è il posto più logico ma non l’ho verificato; si dovrebbe rimuovere solo il frammento, se esiste, aggiunto con il bottone, basandosi ad esempio su un tag che identifica quel frammento; ho avuto un problema simile di frammenti che si sovrapponevano e ho risolto con l’uso combinato dei metodi attach e detach.

Ho risolto il problema della sovrapposizione modificando in questo modo il metodo:
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(, mFragment, mTag);
} else {
if (mFragment.getTag().equals(getFragmentManager().findFragmentById(;
else {
if (mFragment == null)
{ mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(, mFragment, mTag);}
{ ft.attach(mFragment);

Ho testato il codice in varie situazioni e non ha dato problemi ma in questo modo permane ancora l’altro problema ovvero, se, dopo aver visualizzato il Fragment N, seleziono dall’ActionBar il tab 2 e poi ritorno sul tab1, quest’ultimo compare vuoto ovvero non visualizzo più il suo Layout.

ft.replace(…) equivale a un remove del precedente frammento + un add del nuovo frammento, e quindi il vecchio frammento non esiste più in quanto sostituito (eliminato).
O si ricrea il frammento della prima tab quando da tab2 si passa a tab1 oppure si potrebbe verificare cosa succede usando invece del replace() la sequenza hide(frammento da sostituire) + add(frammento nuovo N)

i have tried this example with the ActionBarSherlock and every time i’m using the addTab my programs crashed. does anyone knows how i can fix it?

The activity is destroyed and restarted when you rotate the device; in order to avoid this you insert the following line inside the “activity” tag in AndroidManifest.xml

I noticed the uppercase, I’m thinking of writing a post if I found the solution, but maybe it is not possible.
Consider that in Android Design Google puts all labels of the tabs in upper case.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.