Create a tab layout on Android

What is Tab Layout

I was working on a tabbed screen for saved offers. See below for screenshot.

Create The Layout

The entire offer screen is a Fragment. What I did is to include a Tab Layout in layout .xml file. Added the following code into the top of the fragment layout file.

1
2
3
4
5
6
7
8
9
10
11
12
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="@dimen/deal_list_tab_height">

<!-- Add items directly from XML -->
<android.support.design.widget.TabItem
android:text="@string/tab_text"/>

<android.support.design.widget.TabItem
android:icon="@drawable/ic_android"/>

</android.support.design.widget.TabLayout>

You can visit the TabLayout page for more details.

Add Tab Items Programmatically

You can either add tab items in Layout file or create tab items programatically.

To create tab items programatically, you will first need to assign an ID to TabLayout so that you can get the TabLayout in Fragment.

1
2
3
4
final TabLayout tabLayout = view.findViewById(R.id.deal_tab_main);
TabLayout.Tab tab = tabLayout.newTab();
tab.setText(getContext().getText(R.string.tab_title_1));
tabLayout.addTab(tab);

Tab Tapped

When user tap on a tab, there are two things you can do. One thing is to switch to a different fragment. The other is to reload data for the current fragment. For us, I choose to reload the offer list.

If you want to switch to a different fragment, check ViewPager .

If you want to reload data when select another tab, use the OnTabSelectedListener. See below for the actual code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tabLayout.addOnTabSelectedListener(new OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
// Tab Selected
Log.d(getClass().getName(), "Selected Position: tab.getPosition()");
}

@Override
public void onTabUnselected(TabLayout.Tab tab) {
// Ignored ....
}

@Override
public void onTabReselected(TabLayout.Tab tab) {
// Ignored ....
}
});

Dynamically Create Tab Layout Using Enum

I end up using a enum for creating the tab. I add tab items programatically depending on items in an enum. So this is what I did.

First, put the enum somewhere:

1
2
3
public enum DealsShowType {
ALL, SAVED
}

Then, create the tab items dynamically depending on the DealsShowType enums:

1
2
3
4
5
6
7
8
9
10
11
12
13
final TabLayout tabLayout = view.findViewById(R.id.deal_tab_main);
for (DealsListViewModel.DealsShowType type : DealsListViewModel.DealsShowType.values()) { // for loop enum
TabLayout.Tab tab = tabLayout.newTab();
switch (type) {
case ALL:
tab.setText(getContext().getText(R.string.deals_list_tab_show_all));
break;
case SAVED:
tab.setText(getContext().getText(R.string.deals_list_tab_show_saved));
break;
}
tabLayout.addTab(tab);
}

Last but not least, refresh data when tab gets pressed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
tabLayout.addOnTabSelectedListener(new OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
showType = DealsListViewModel.DealsShowType.values()[tab.getPosition()]; // know which enum is currently selected
modelsFetched();
// model fetched will access class variable showType to correctly fetch data depending on the current type.
}

@Override
public void onTabUnselected(TabLayout.Tab tab) {
// Ignored ....
}

@Override
public void onTabReselected(TabLayout.Tab tab) {
// Ignored ....
}
});