Fragment

Android Fragment Tabs Example

As title clarifies, today we ‘re gonna see how to implement a Tab Layout using Fragments. Regarding the previous versions of Android, a Tab Layout could be implemented using TabWidget and TabHost, but now, these are deprecated, so we have to find another workaround, if we don’t want to directly use Google’s solution.

So, today, another easy example: we ‘ll create three (3) tabs (they correspond to my most-driven cars), which will contain fragments; Android Fragments must be setup using Listeners – you ‘ll see what I mean while moving on.

For the need of this example, we will use the following tools in a Windows 64-bit platform:

  1. JDK 1.7
  2. Eclipse 4.4 Luna
  3. Android SDK 4.4
Tip
You may skip project creation and jump directly to the beginning of the example below.

1. Creating a New Android Application Project

Open Eclipse IDE and go to File → New → Project → Android Application Project.

Fill in the name of the application, the project and the package in the appropriate fields and then click Next.

Figure 1. Create a new Android application
Figure 1. Create a new Android application

In the next window, the “Create Activity” option should be checked. The new created activity will be the main activity of your project. Then press Next button.

Figure 2. Configure the project
Figure 2. Configure the project

In “Configure Launcher Icon” window you should choose the icon you want to have in your app. We will use the default icon of android, so click Next button.

Figure 3. Configure the launcher icon
Figure 3. Configure the launcher icon

Select the “Blank Activity” option and press Next.

Figure 4. Create the activity and select its type
Figure 4. Create the activity and select its type

You then have to specify a name for the new Activity and a name for the layout description of your app. The .xml files for the layout will automatically be created in the res/layout folder. Finally, press Finish.

Figure 5. Create a new blank activity
Figure 5. Create a new blank activity

Here is the very final structure of the project, just in case you ‘ll miss something, while developing:

Figure 6. The final structure of the project
Figure 6. The final structure of the project

2. Creating the layout of the Main Activity

Let’s do it by opening res/layout/activity_main.xml and navigating to the respective xml tab and paste the following.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

This is about the main screen that our tabs will be hosted on; there come’s the ActionListener that I fore-mentioned. Especially, we here deal with ActionBar.TabListener.

We ‘ll override its methods, but we don’t actually need the first parameter of them ( tab ), as we ‘ll use Fragment elements. Doing so, means that each time that our TabListener is called, a user action occurs (in our case, the only user action is the tabs’ transition), so we have to conform our TabListener in order to automatically change the layout, according to the selected tab.

Each tab’s content will be in a separate layout file (so, three extra in overall, one for each tab), but the actual transition will be implemented in the MainActivity, using TabListeners for each tab.

I ‘ll leave the rest of your “gaps” to be filled, while reading TabListener‘s comments; you ‘ll find this way more mind-sharpening.

But why to use a FrameLayout?
This and this will resolve this issue, too.

3. Coding the Main Activity

Let’s first navigate to src/com.javacodegeeks.android.textviewtest/MainActivity.java. Next, complete the class like this:

MainActivity.java

package com.javacodegeeks.android.tablayout_with_fragments;

import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;

public class MainActivity extends Activity {

	// Declaring our tabs and the corresponding fragments.
	ActionBar.Tab bmwTab, fordTab, toyotaTab;
	Fragment bmwFragmentTab = new BmwFragmentTab();
	Fragment toyotaFragmentTab = new ToyotaFragmentTab();
	Fragment fordFragmentTab = new FordFragmentTab();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		// Asking for the default ActionBar element that our platform supports.
		ActionBar actionBar = getActionBar();
		 
        // Screen handling while hiding ActionBar icon.
        actionBar.setDisplayShowHomeEnabled(false);
 
        // Screen handling while hiding Actionbar title.
        actionBar.setDisplayShowTitleEnabled(false);
 
        // Creating ActionBar tabs.
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
 
        // Setting custom tab icons.
        bmwTab = actionBar.newTab().setIcon(R.drawable.bmw_logo);
        toyotaTab = actionBar.newTab().setIcon(R.drawable.toyota_logo);
        fordTab = actionBar.newTab().setIcon(R.drawable.ford_logo);
        
        // Setting tab listeners.
        bmwTab.setTabListener(new TabListener(bmwFragmentTab));
        toyotaTab.setTabListener(new TabListener(toyotaFragmentTab));
        fordTab.setTabListener(new TabListener(fordFragmentTab));
       
        // Adding tabs to the ActionBar.
        actionBar.addTab(bmwTab);
        actionBar.addTab(toyotaTab);
        actionBar.addTab(fordTab);
	}
}

Let’s stick to the difficult part of it: line 11 declares three ActionBar tabs, while in lines 39-41, a TabListener is assigned to each one of them, according to the specific Fragment that it corresponds to (lines 12-14). What lines 39-41 also make clear is, that we have to code a constructor, for the TabListener class.

In addition to the fore-mentioned class, we also have to write three extra classes, as lines 12-14 clarify.

4. Coding the “extra” Classes

Let’s start by writing the TabListener class.

TabListener.java

package com.javacodegeeks.android.tablayout_with_fragments;

import android.app.ActionBar.Tab;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.ActionBar;

public class TabListener implements ActionBar.TabListener {

	private Fragment fragment;
	
	// The contructor.
	public TabListener(Fragment fragment) {
		this.fragment = fragment;
	}

	// When a tab is tapped, the FragmentTransaction replaces
	// the content of our main layout with the specified fragment;
	// that's why we declared an id for the main layout.
	@Override
	public void onTabSelected(Tab tab, FragmentTransaction ft) {
		ft.replace(R.id.activity_main, fragment);
	}

	// When a tab is unselected, we have to hide it from the user's view. 
	@Override
	public void onTabUnselected(Tab tab, FragmentTransaction ft) {
		ft.remove(fragment);
	}

	// Nothing special here. Fragments already did the job.
	@Override
	public void onTabReselected(Tab tab, FragmentTransaction ft) {
		
	}
}

We ‘ll continue by adding the classes, that refer to the make’s FragmentTab.

BmwFragmentTab.java

package com.javacodegeeks.android.tablayout_with_fragments;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.app.Fragment;
 
public class BmwFragmentTab extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.bmw_layout, container, false);
        return rootView;
    }
}

What we accomplished here is creating an independent Fragment tab (regarding our BMW category), whom’s onCreate method results to the corresponding xml layout (a simple TextView that contains my personal experience, according to the specified make).

ToyotaFragmentTab.java

package com.javacodegeeks.android.tablayout_with_fragments;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.app.Fragment;
 
public class ToyotaFragmentTab extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.toyota_layout, container, false);
        return rootView;
    }
}

Continuing on the same concept with BmwFragmentTab, we here point the ToyotaFragmentTab to the toyota_layout (no need for worries till here, as this is about simple layouts, as I fore-mentioned, which we ‘ll code in the next paragraph).

FordFragmentTab.java

package com.javacodegeeks.android.tablayout_with_fragments;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.app.Fragment;
 
public class FordFragmentTab extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.ford_layout, container, false);
        return rootView;
    }
}

Same here, a FragmentTab that points the layout we need.

5. Coding the “extra” layouts

What is clear from the previous paragraph, is the fact that we need three xml layouts, to host our FragmentTabs’ user interface. A simple TextView for each one, as I said.

bmw_layout.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="Yes, I'm a proud E46-er!" />
 
</RelativeLayout>

toyota_layout.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="You mud? Toyota Hilux 2.4TD!" />
 
</RelativeLayout>

ford_layout.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="God, help the poor man that bought my Fiesta." />
 
</RelativeLayout>

6. Running the application

Figure 7. Initial state of the app - first tab is selected by default
Figure 7. Initial state of the app – first tab is selected by default

Let’s tap the other two tabs, too!

Figure 8. Tapping the second tab
Figure 8. Tapping the second tab

Figure 9. Tapping the third tab
Figure 9. Tapping the third tab

7. Source Code Download

Cheers!
This was an example of Fragment Tabs in Android. You can also download the source code for this example: TabLayout_with_Fragments.zip

Thodoris Bais

Thodoris is an Oracle Certified Associate Java Programmer and currently works as a Junior Software Developer, for Intrasoft International S.A. He holds a diploma at Informatics & Telecommunications Engineering and is interested in continuous development.
Subscribe
Notify of
guest

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

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button