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 TabActionBarActivity.java
  2. edit the file AndroidManifest.xml, it should be the default one
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="eu.lucazanini"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk android:minSdkVersion="15" />
    
        <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name" >
            <activity
                android:name=".TabActionBarActivity"
                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>
    
  3. edit the file /res/values/strings.xml, to manage the labels
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <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>
    </resources>
    
  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="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
    </LinearLayout>
    
  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="http://schemas.android.com/apk/res/android"
        android:id="@+id/tab1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" 
        android:gravity="center">
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="@string/body1" />
    
    </LinearLayout>
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/tab2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" 
        android:gravity="center">
    
        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="@string/body2" />
    
    </LinearLayout>
    
  6. edit the class TabActionBarActivity.java, 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.app.ActionBar;
    import android.app.ActionBar.Tab;
    import android.app.Activity;
    import android.app.Fragment;
    import android.app.FragmentTransaction;
    import android.os.Bundle;
    
    public class TabActionBarActivity extends Activity {
    
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    
    		ActionBar actionBar = getActionBar();
    
    		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    
    		String label1 = getResources().getString(R.string.label1);
    		Tab tab = actionBar.newTab();
    		tab.setText(label1);
    		TabListener<Tab1Fragment> tl = new TabListener<Tab1Fragment>(this,
    				label1, Tab1Fragment.class);
    		tab.setTabListener(tl);
    		actionBar.addTab(tab);
    
    		String label2 = getResources().getString(R.string.label2);
    		tab = actionBar.newTab();
    		tab.setText(label2);
    		TabListener<Tab2Fragment> tl2 = new TabListener<Tab2Fragment>(this,
    				label2, Tab2Fragment.class);
    		tab.setTabListener(tl2);
    		actionBar.addTab(tab);
    
    	}
    
    	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(android.R.id.content, mFragment, mTag);
    			} else {
    				// If it exists, simply attach it in order to show it
    				ft.attach(mFragment);
    			}
    		}
    
    		public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    			if (mFragment != null) {
    				// Detach the fragment, because another one is being attached
    				ft.detach(mFragment);
    			}
    		}
    
    		public void onTabReselected(Tab tab, FragmentTransaction ft) {
    			// User selected the already selected tab. Usually do nothing.
    		}
    	}
    
    }
    
  7. create the classes Tab1Fragment.java and Tab2Fragment.java
    package eu.lucazanini;
    
    import android.app.Fragment;
    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 {
    
    	@Override
    	public View onCreateView(LayoutInflater inflater, ViewGroup container,
    			Bundle savedInstanceState) {
    
    		return (LinearLayout) inflater.inflate(R.layout.tab1, container, false);
    	}
    
    }
    
    package eu.lucazanini;
    
    import android.app.Fragment;
    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 {
    
    	@Override
    	public View onCreateView(LayoutInflater inflater, ViewGroup container,
    			Bundle savedInstanceState) {
    
    		return (LinearLayout) inflater.inflate(R.layout.tab2, container, false);
    	}
    
    }
    
  8. launch the app

Comments

115 responses to “Tab Layout in Android with ActionBar and Fragment”

  1. 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.

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

  3. 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?

  4. Hi Luca,

    thank you so much for this fine tutorial. I had sooo many problems to implement it but your tutorial show me the right way.

  5. Alberto Avatar

    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?

    grazie!

  6. Alberto Avatar

    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(R.id.tv1);
    tv.setText(….)

    ottengo nullPointerException

    1. Il codice sembra corretto, forse il problema è nel xml

  7. Vineet B Avatar
    Vineet B

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

    1. See this.
      Maybe it is what you ask.

      1. Vineet B Avatar
        Vineet B

        Got it working. Thnx.

  8. Hi,
    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.

    1. 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.

  9. sarkhelritesh Avatar
    sarkhelritesh

    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.

  10. how to get the tabs to the middle of the actionbar ??

    1. No, you can’t using an action bar.

  11. […] the post Tab Layout in Android with ActionBar and Fragment the fragments can’t be replaced later, in this post I write the changes in order to replace […]

  12. Babu Subramanian Avatar
    Babu Subramanian

    It worked like a charm. Thanks Luca for your excellent tutorial!

  13. Ciao Luca,
    volevo chiederti una cosa:
    ho seguito l’esempio “Adding Navigation Tabs” alla pagina: http://developer.android.com/guide/topics/ui/actionbar.html
    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 🙂

    Armando

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

    I want that tabs should fill whole actionbar.

  15. Ciao,
    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.

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

      actionBar.setDisplayShowHomeEnabled(false);
      actionBar.setDisplayShowTitleEnabled(false);
      

      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.

  16. 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?

    Thanks.

    1. Check if the line 76 in TabActionBarActivity.java, ft.detach(mFragment), is executed.

      1. You are right! Now is running fine.
        Thank you very much.

  17. Haripoter Avatar

    Hi,

    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
    FragmentTransaction.replace()

    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?

    1. 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.

      1. Haripoter Avatar

        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?

        1. onBackPressed() is an Activity method, added in API level 5.

  18. action bar example coding is very nice
    very very thanks

  19. Varun Parikh Avatar
    Varun Parikh

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

    1. You are right, I don’t use main.xml here so you can remove it.
      Thanks.
      You can’t use gestures to swap the tabs in this esample.

  20. 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.

    1. hemoali Avatar
      hemoali

      Same problem here

  21. how to create the tab in middle of the screen???

    1. Luca Zanini Avatar
      Luca Zanini

      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.

  22. You are a hero. Thankyou so much.

  23. Is it possible the actionbar tabs to navigate to activities instead of fragments?

    1. Luca Zanini Avatar
      Luca Zanini

      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.

  24. Hi,

    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.

    1. Luca Zanini Avatar
      Luca Zanini

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

  25. anpadh Avatar

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

    1. Luca Zanini Avatar
      Luca Zanini

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

  26. dnoray Avatar

    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?

    1. Luca Zanini Avatar
      Luca Zanini

      My answer is here

  27. 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(R.id.main_drink_list_btn);
    drinkListBtn.setOnClickListener(new OnClickListener() {

    @Override
    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

    1. Luca Zanini Avatar
      Luca Zanini

      Your code is ok, it runs on my pc without errors.

  28. Hi,

    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.

    Thanks

    1. Luca Zanini Avatar
      Luca Zanini

      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.

  29. 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

    1. Luca Zanini Avatar
      Luca Zanini

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

  30. Felipe Costa Avatar
    Felipe Costa

    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?

    1. Luca Zanini Avatar
      Luca Zanini

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

      1. Felipe Costa Avatar
        Felipe Costa

        Luca,

        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.

        1. Luca Zanini Avatar
          Luca Zanini

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

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

          the onCreateView and onActivityCreated methods are not called.

  31. 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”.
    Thanks…

    1. Luca Zanini Avatar
      Luca Zanini

      Use ImageView instead of TextView in xml resource, see Bitmap File example in Drawable Resources

  32. Hi!

    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.

    1. Luca Zanini Avatar
      Luca Zanini

      Is the tab widget displayed on the right side of the app name? not under the app name?
      It seems a menu: Creating an Options Menu

  33. 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?

    1. Luca Zanini Avatar
      Luca Zanini

      Check if New_tab extends android.app.Fragment

      1. thanks, for anyone else who runs into the problem, more specifically it was changing import android.support.v4.app.Fragment; to import android.app.Fragment;

  34. […] The idea for this post came to me after reading the comment of Esthon Wood: “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.” in the post Tab Layout in Android with ActionBar and Fragment. […]

  35. […] the post Tab Layout in Android with ActionBar and Fragment I wrote an example about tabs in an action bar where each label open a fragment that you can not […]

  36. Hello

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

    This is how i create my tabs

    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    Tab tabA = actionBar.newTab();
    tabA.setText(R.string.tab1);
    tabA.setTabListener(this);
    actionBar.addTab(tabA); //same for the other tabs

    Then i implement the ActionBar.TabListener

    @Override
    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(R.id.container, fragment);
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    transaction.commit();
    }
    }
    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }
    @Override
    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(R.id.container, fragment);
    transaction.addToBackStack(null);
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    transaction.commit();

    Thanks

  37. 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…

    THANK YOU

    1. Luca Zanini Avatar
      Luca Zanini

      I believe you can’t put the ActionBar at the bottom but you can custom using the method setCustomView

  38. Esthon Wood Avatar
    Esthon Wood

    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 🙂

    1. Luca Zanini Avatar
      Luca Zanini

      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(R.id.webView1);
      	webView.loadUrl("http://www.google.com");
      
      	return ll;
          }
      

      This code requires

      private WebView webView;
      

      Remember to add the permission

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

      in your AndroidManifest.xml

      1. Esthon Wood Avatar
        Esthon Wood

        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 =)

  39. Jack Tsao Avatar

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

  40. Thanks for the tutorial.. found this after searching for 2 days and it solved the problem for me.

  41. 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)

    Thanks

    1. Luca Zanini Avatar
      Luca Zanini

      You can replace onCreateView in Tab1Fragment.java

          public View onCreateView(LayoutInflater inflater, ViewGroup container,
      	    Bundle savedInstanceState) {
      	LinearLayout ll = (LinearLayout) inflater.inflate(R.layout.tab1,
      		container, false);
      
      	TextView tv = (TextView) ll.findViewById(R.id.textView1);
      	tv.setOnClickListener(new OnClickListener() {
      	    public void onClick(View v) {
      		// your code goes here
      		Toast t = Toast.makeText(getActivity(), "bye",
      			Toast.LENGTH_LONG);
      		t.show();
      	    }
      	});
      
      	return ll;
          }
      

      Otherwise you can implement OnClickListener in the class Tab1Fragment.

  42. Thank you soou much for your tutorial man. I have been searching for tabs with fragments tutorial for two hours and this one did the magic. Keep up the good work 🙂

  43. Thank u lot for this useful tutorial

  44. Thank you a lot for taking the time to write this tutorial! saved me a lot of time.

    God Bless!

  45. Hi,

    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?

    Regards,
    Bhavin.

  46. 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.

    1. Luca Zanini Avatar
      Luca Zanini

      To manage the fragments you can use the FragmentTransaction class and its methods.
      See http://developer.android.com/guide/components/fragments.html under the section “Managing Fragments”

  47. 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.

    1. Luca Zanini Avatar
      Luca Zanini

      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.

      1. Sukhwinder Avatar
        Sukhwinder

        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.

        1. Luca Zanini Avatar
          Luca Zanini

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

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

        <string name="action_settings">Settings</string>
        
        1. Luca Zanini Avatar
          Luca Zanini

          Not used.

  48. 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.
    Thanks!

    1. Luca Zanini Avatar
      Luca Zanini

      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.

  49. 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.

    1. Luca Zanini Avatar
      Luca Zanini

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

      1. 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.

        1. Luca Zanini Avatar
          Luca Zanini

          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: android.R.id.content

          1. 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).

          2. Luca Zanini Avatar
            Luca Zanini

            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.

        2. 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?

          1. Luca Zanini Avatar
            Luca Zanini

            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.

          2. 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(android.R.id.content, mFragment, mTag);
            } else {
            if (mFragment.getTag().equals(getFragmentManager().findFragmentById(android.R.id.content).getTag()))
            ft.show(mFragment);
            else {
            ft.detach(getFragmentManager().findFragmentById(android.R.id.content));
            if (mFragment == null)
            { mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment, mTag);}
            else
            { 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.

          3. Luca Zanini Avatar
            Luca Zanini

            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)

  50. […] the post Tab Layout in Android with ActionBar and Fragment I explain how to implement tabs and in the post Swipe views I explain how to implement the swipe […]

  51. 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?

  52. If you`re on the second tab and you change the tablet orientation you app “restart” and you back to the first tab.
    How fix this?

    1. Luca Zanini Avatar
      Luca Zanini

      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
      android:configChanges=”orientation|screenSize”

      1. In this case if activity is in landscape orientation the Tabs are not clickable, what to do?

  53. Thank god for this tutorial.
    I’ve been pulling my hair for two days now.

    Thanks!

  54. […] a previous post I implemented a layout with 2 tabs using an action bar and fragments; the disadvantage of this […]

  55. Excellent! This saved me so much time. Thanks!

  56. Hi

    I realised the text in the tab are in uppercase. Is there a way to change it to lowercase?

    1. Luca Zanini Avatar
      Luca Zanini

      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.