In this article, we will see an example of TabLayout. A TablLayout is part of the support design library to provide the horizontal layout to display tabs. We will also make use of ViewPager to associate a tab with a child view. In order to view the page, user can either select tab or simply swipe between the views.
Set up
- Your Android Gradle plugin version must be at least v1.2.3. Here is the project’s gradle build file.build.gradle:
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.2.3' } } allprojects { repositories { jcenter() } }
- In order to use the latest designs in older Android platforms, we need to add support libraries. See Support Library Setup to know more about how to download and setup the support libraries.
- Include
'com.android.support:appcompat-v7:23.0.0'
to the module’s gradle build file to add support library. - Include
'com.android.support:support-v13:22.2.1'
to add support for theFragment
user interface and additional fragment support classes. - We also need to include the support design library
'com.android.support:design:22.2.1'
, this is required to access theTabLayout
feature. - In order to use ViewPager, you also need to include support-v4 library bitsince AppCompat library has an implicit dependency on the support-v4 library you don’t have to explicitly declare it in the gradle build file.
- Modify the module’s gradle build file to include the support libraries specified abovebuild.gradle:
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.0" defaultConfig { applicationId "com.javarticles.tabs" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.0.0' compile 'com.android.support:support-v13:22.2.1' compile 'com.android.support:design:22.2.1' }
Sliding Tabs Layout – Layout composed of TabLayout and ViewPager
android.support.design.widget.TabLayout
represents tab layout, we will use it for rendering the different tab options. The android.support.v4.view.ViewPager
component will be used to page between the various fragments we will create. We will include both these components within a RelativeLayout
.
Here is the mock TabLayout Layout that we want to see.
and here is the layout XML.
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/root_view_main" android:layout_width="match_parent" android:layout_height="match_parent"> <com.javarticles.tabs.PianoClassesTabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/tab_background" app:tabIndicatorColor="@color/tab_indicator" /> <android.support.v4.view.ViewPager android:id="@+id/viewpager_main" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/tab_layout" /> </RelativeLayout>
Class PianoClassesTabLayout
is a custom android.support.design.widget.TabLayout
. Later we will add methods to create tabs and the tab icons.
PianoClassesTabLayout:
package com.javarticles.tabs; import android.content.Context; import android.support.annotation.DrawableRes; import android.support.annotation.StringRes; import android.support.design.widget.TabLayout; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; public class PianoClassesTabLayout extends TabLayout { public PianoClassesTabLayout(Context context) { super(context); } public PianoClassesTabLayout(Context context, AttributeSet attrs) { super(context, attrs); } public PianoClassesTabLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } .... }
Create Fragments
As we select each tab, the content related to the tab will be shown. Since each tab is just a fragment, we need to create and define the Fragment to be shown. In our example, we have two tabs, the first one is about the tutor and the other tab is about piano courses.
Here is the tutor layout.
tutor_layout.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/about_tutor" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/tutor_details" /> </LinearLayout>
and the courses layout.
courses_layout.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/about_course" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/course_details" /> </LinearLayout>
In onCreateView()
, we will the fragment and return the tab content:
PianoTutorFragment:
package com.javarticles.tabs; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class PianoTutorFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.tutor_layout, container, false); return rootView; } }
CoursesFragment:
package com.javarticles.tabs; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class CoursesFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.courses_layout, container, false); return rootView; } }
strings.xml:
<resources> <string name="app_name">TabExample</string> <string name="about_tutor">About Tutor</string> <string name="about_course">About Course</string> <string name="courses">Courses</string> <string name="hello_world">Hello world!</string> <string name="action_settings">Settings</string> <string name="tutor_details">He is training students in Piano for ABRSM university, UK for the past 10 years. He is known for his specified and individual approaches to each and every student.</string> <string name="course_details">We are conducting summer classes for 2 different age groups. (4 – 10 years and 11 – 16 years.) It will be a fun–filled learning experience to improve their skills and also define their interests towards different activities.</string> </resources>
Implement FragmentPagerAdapter
In order to associate a tab with page content, we implement the adapter for the ViewPager
. We implement getItem(int position)
, which determines the fragment to show based on the tab’s position.
PianoTabAdapter:
package com.javarticles.tabs; import android.app.Fragment; import android.app.FragmentManager; import android.support.v13.app.FragmentStatePagerAdapter; import android.util.SparseArray; import android.view.ViewGroup; public class PianoTabAdapter extends FragmentStatePagerAdapter { public PianoTabAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { switch (position) { case 0: return new PianoTutorFragment(); case 1: return new CoursesFragment(); default: return null; } } @Override public int getCount() { return 2; } }
Setting up Sliding Tabs
Let’s now come to the main activity, so what do we do here?
- We inflate the main layout composed of the tab layout and view pager.
setContentView(R.layout.activity_main);
- We find the
ViewPager
andTabLayout
, attach ourViewPager
to thePianoTabAdapter
mViewPager = (ViewPager) findViewById(R.id.viewpager_main); mTabLayout = (PianoClassesTabLayout) findViewById(R.id.tab_layout); mTabAdapter = new PianoTabAdapter(getFragmentManager()); mViewPager.setAdapter(mTabAdapter);
- Next, we create tabs.
mTabLayout.createTabs();
- As we select the tab, we want the page view to change.
mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { mViewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(TabLayout.Tab tab) { // nop } @Override public void onTabReselected(TabLayout.Tab tab) { } });
PianoClassesMainActivity:
package com.javarticles.tabs; import android.app.Activity; import android.app.Fragment; import android.support.design.widget.TabLayout; import android.support.v4.view.ViewPager; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; public class PianoClassesMainActivity extends Activity { private ViewPager mViewPager; private PianoTabAdapter mTabAdapter; private PianoClassesTabLayout mTabLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewPager = (ViewPager) findViewById(R.id.viewpager_main); mTabLayout = (PianoClassesTabLayout) findViewById(R.id.tab_layout); mTabAdapter = new PianoTabAdapter(getFragmentManager()); mViewPager.setAdapter(mTabAdapter); mTabLayout.createTabs(); mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { mViewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(TabLayout.Tab tab) { // nop } @Override public void onTabReselected(TabLayout.Tab tab) { } }); } }
Adding Icons to the Layout
As we create the tabs, we also set the custom view of the tab.
Tab tab = newTab(); tab.setCustomView(tabView).setContentDescription(contentDescriptionId); addTab(tab);
The custom view can either contain just the image view or image view along with a title. In the below custom view, we just include an ImageView
.
tab_icon.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="@dimen/toolbar_height"> <ImageView android:id="@+id/tab_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:src="@drawable/tab_piano_tutor" /> </RelativeLayout>
We will inflate the above custom view and set the image resource to a drawable XML.
View tabView = LayoutInflater.from(getContext()).inflate(R.layout.tab_icon, null); ImageView imageView = (ImageView) tabView.findViewById(R.id.tab_icon); imageView.setImageResource(iconId);
We associate a tab to a drawable resource as we create them.
public void createTabs() { addTab(R.drawable.tab_piano_tutor, R.string.about_tutor); addTab(R.drawable.tab_piano_courses, R.string.courses); }
Here is the complete TabLayout
class.
PianoClassesTabLayout:
package com.javarticles.tabs; import android.content.Context; import android.support.annotation.DrawableRes; import android.support.annotation.StringRes; import android.support.design.widget.TabLayout; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; public class PianoClassesTabLayout extends TabLayout { public PianoClassesTabLayout(Context context) { super(context); } public PianoClassesTabLayout(Context context, AttributeSet attrs) { super(context, attrs); } public PianoClassesTabLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void createTabs() { addTab(R.drawable.tab_piano_tutor, R.string.about_tutor); addTab(R.drawable.tab_piano_courses, R.string.courses); } private void addTab(@DrawableRes int iconId, @StringRes int contentDescriptionId) { View tabView = LayoutInflater.from(getContext()).inflate(R.layout.tab_icon, null); ImageView imageView = (ImageView) tabView.findViewById(R.id.tab_icon); imageView.setImageResource(iconId); Tab tab = newTab(); tab.setCustomView(tabView).setContentDescription(contentDescriptionId); addTab(tab); } }
Tab’s Drawable Resource
tab_piano_courses.xml:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/ic_tab_piano_pressed" android:state_selected="true" /> <item android:drawable="@drawable/ic_tab_piano_normal" /> </selector>
tab_piano_tutor.xml:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/ic_tab_about_tutor_pressed" android:state_selected="true" /> <item android:drawable="@drawable/ic_tab_about_tutor_normal" /> </selector>
Tab’s normal and pressed state
Here is the image that represents the normal state.
Tutor’s image in 9-patch format. This one represents pressed state of the tab.
For the courses icon, we have used individual icons for each resolution.
Run the application
Tutor Tab
Courses Tab
Download the source code
This was an example about Android TabLayout.