In Android app development, tab layouts are a common UI pattern for organizing content into separate sections, allowing users to switch between different views with ease. Using XML along with ViewPager to create tab layouts remains a viable approach, especially for projects that haven’t migrated to Jetpack Compose. This article provides a comprehensive guide on building tab layouts using XML and ViewPager.
What is a Tab Layout?
A tab layout is a UI element that displays a horizontal series of tabs, each representing a different view or section of content. Tapping on a tab navigates the user to the associated view, which is typically displayed within a container such as a ViewPager.
Why Use XML and ViewPager?
- Wide Compatibility: Compatible with older Android versions, making it suitable for projects with broad device support requirements.
- Simplicity: Straightforward implementation for simple tab layouts without requiring complex state management.
- Established Pattern: Familiarity among developers, facilitating easier maintenance and updates.
How to Build Tab Layouts in XML Using ViewPager
To implement a tab layout using XML and ViewPager, follow these steps:
Step 1: Add Dependencies
Ensure that you have the necessary dependencies in your build.gradle
file. If you’re using AndroidX, add the AndroidX version of the support libraries:
dependencies {
implementation 'com.google.android.material:material:1.6.0' // or newer
implementation 'androidx.viewpager:viewpager:1.0.0'
}
If you’re still using the legacy support libraries:
dependencies {
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
}
Choose the dependencies based on whether your project is using AndroidX or the older support libraries.
Step 2: Create the Layout XML File
Create the main layout XML file (e.g., activity_main.xml
) to define the TabLayout and ViewPager:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"/>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
In this layout:
TabLayout
is used to display the tabs.ViewPager
is used to swipe between different views.tabMode="fixed"
ensures that all tabs are visible, andtabGravity="fill"
distributes tabs evenly across the TabLayout.
Step 3: Create Fragment Layouts
Create individual layout XML files for each tab’s content. For example:
fragment_tab1.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFEB3B">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Tab 1 Content"
android:textSize="20sp"/>
</FrameLayout>
fragment_tab2.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#4CAF50">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Tab 2 Content"
android:textSize="20sp"/>
</FrameLayout>
fragment_tab3.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F44336">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Tab 3 Content"
android:textSize="20sp"/>
</FrameLayout>
Step 4: Create Fragments
Create Fragments corresponding to each tab. For example:
Tab1Fragment.java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
public class Tab1Fragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tab1, container, false);
}
}
Tab2Fragment.java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
public class Tab2Fragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tab2, container, false);
}
}
Tab3Fragment.java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
public class Tab3Fragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tab3, container, false);
}
}
Step 5: Create a PagerAdapter
Create a custom PagerAdapter to manage the Fragments within the ViewPager:
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import java.util.ArrayList;
import java.util.List;
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
Step 6: Set up the Activity
In your Activity (e.g., MainActivity.java
), set up the ViewPager and TabLayout:
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private TabLayout tabLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.viewPager);
tabLayout = findViewById(R.id.tabLayout);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new Tab1Fragment(), "Tab 1");
adapter.addFragment(new Tab2Fragment(), "Tab 2");
adapter.addFragment(new Tab3Fragment(), "Tab 3");
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
}
}
Key components:
- Initialize
ViewPager
andTabLayout
from the layout XML. - Create an instance of
ViewPagerAdapter
and add Fragments to it. - Set the adapter for the
ViewPager
. - Use
tabLayout.setupWithViewPager(viewPager)
to link the TabLayout with the ViewPager.
Advanced Customization
You can further customize the appearance and behavior of the TabLayout:
- Custom Tab Views: Use custom layouts for individual tabs to add icons or other UI elements.
- Tab Indicators: Change the color, height, and other properties of the tab indicator using XML attributes or programmatically.
- Tab Listeners: Implement
TabLayout.OnTabSelectedListener
to respond to tab selection events and perform actions accordingly.
Here is an example on how to change the colors of tabs
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
app:tabTextColor="@color/tab_text_color"
app:tabSelectedTextColor="@color/tab_selected_text_color"
app:tabIndicatorColor="@color/tab_indicator_color"/>
Conclusion
Building tab layouts in XML using ViewPager is a straightforward and widely adopted approach for creating tabbed interfaces in Android apps. By following the steps outlined in this guide, developers can create functional and visually appealing tab layouts, providing users with an intuitive way to navigate through different sections of content. While modern alternatives like Jetpack Compose offer more advanced capabilities, using XML and ViewPager remains a valuable technique for projects requiring compatibility with older Android versions or simpler implementations.