Wednesday, June 20, 2012

Create ActionBar in Tab navigation mode

ActionBar in Tab navigation mode

ActionBar in Tab navigation mode


New a Android project target Android 3.2, API Level 13.

Create three Fragments, each one corresponding to one tab.

MyFragmentA.java
package com.exercise.AndroidNavigationTabs;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyFragmentA extends Fragment {

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {
  View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
  return myFragmentView;
 }

}


/res/layout/fragment_a.xml
<?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" >
   <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="It's Fragment A" />
   <ImageView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:src="@drawable/ic_launcher"/>
</LinearLayout>


MyFragmentB.java
package com.exercise.AndroidNavigationTabs;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyFragmentB extends Fragment {

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {
  View myFragmentView = inflater.inflate(R.layout.fragment_b, container, false);
  return myFragmentView;
 }

}


/res/layout/fragment_b.xml
<?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" >
   <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="It's Fragment B" />
   <ImageView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:scaleType="center"
       android:src="@drawable/ic_launcher"/>
</LinearLayout>


MyFragmentC.java
package com.exercise.AndroidNavigationTabs;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyFragmentC extends Fragment {

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {
  View myFragmentView = inflater.inflate(R.layout.fragment_c, container, false);
  return myFragmentView;
 }

}


/res/layout/fragment_c.xml
<?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" >
   <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="It's Fragment C" />

</LinearLayout>


Main code, AndroidNavigationTabsActivity.java
package com.exercise.AndroidNavigationTabs;

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 AndroidNavigationTabsActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        
        Tab tabA = actionBar.newTab();
        tabA.setText("Tab A");
        tabA.setTabListener(new TabListener<MyFragmentA>(this, "Tag A", MyFragmentA.class));
        actionBar.addTab(tabA);
        
        Tab tabB = actionBar.newTab();
        tabB.setText("Tab B");
        tabB.setTabListener(new TabListener<MyFragmentB>(this, "Tag B", MyFragmentB.class));
        actionBar.addTab(tabB);
        
        Tab tabC = actionBar.newTab();
        tabC.setText("Tab C");
        tabC.setTabListener(new TabListener<MyFragmentC>(this, "Tag C", MyFragmentC.class));
        actionBar.addTab(tabC);
        
        if (savedInstanceState != null) {
            int savedIndex = savedInstanceState.getInt("SAVED_INDEX");
            getActionBar().setSelectedNavigationItem(savedIndex);
        }
        
    }

 @Override
 protected void onSaveInstanceState(Bundle outState) {
  // TODO Auto-generated method stub
  super.onSaveInstanceState(outState);
  outState.putInt("SAVED_INDEX", getActionBar().getSelectedNavigationIndex());
 }

 public static class TabListener<T extends Fragment> 
     implements ActionBar.TabListener{
     
        private final Activity myActivity;
        private final String myTag;
        private final Class<T> myClass;

        public TabListener(Activity activity, String tag, Class<T> cls) {
            myActivity = activity;
            myTag = tag;
            myClass = cls;
        }

  @Override
  public void onTabSelected(Tab tab, FragmentTransaction ft) {

   Fragment myFragment = myActivity.getFragmentManager().findFragmentByTag(myTag);
   
   // Check if the fragment is already initialized
         if (myFragment == null) {
             // If not, instantiate and add it to the activity
             myFragment = Fragment.instantiate(myActivity, myClass.getName());
             ft.add(android.R.id.content, myFragment, myTag);
         } else {
             // If it exists, simply attach it in order to show it
             ft.attach(myFragment);
         }
   
  }

  @Override
  public void onTabUnselected(Tab tab, FragmentTransaction ft) {
   
   Fragment myFragment = myActivity.getFragmentManager().findFragmentByTag(myTag);
   
   if (myFragment != null) {
             // Detach the fragment, because another one is being attached
             ft.detach(myFragment);
         }
   
  }

  @Override
  public void onTabReselected(Tab tab, FragmentTransaction ft) {
   // TODO Auto-generated method stub
   
  }
     
    }
}


Download the files.

Related:
- ViewPager


5 comments:

Captain Harlock said...

Can you explain how the swipe movement should be added to navigate between tabs?

Miguel G. said...

Is it possible to call another fragment from one of these tabs?

For example, my fragment_c.xml is a RelativeLayout with a button on it and also calls for another fragment, but my app crashes when I select it.

Any idea on how I can fix it?

Thanks

RAHULR SANNIDHI said...

please help me to increase the size of the action bar as well as the size of the navigation bar also i'am using the custom theame

Anonymous said...

Strange... I was so happy when I found this example but I cannot get it working...

I always end up with all fragments showing all together in the container...

I am using the support library (action bar as well). I wonder if it comes from that...

Rishabh Sheoran said...

You are the Best!
Its working!!!!!
Thank you! :D