Tabbed with ViewPager in Android: Full Working Guide
Tabs are everywhere in mobile apps. WhatsApp has Chat, Status, and Calls. YouTube has Home, Shorts, and Subscriptions. Instagram has a bottom bar, but many apps still use top tabs for content that fits that pattern. In this guide, I will show you how to build Tabbed with ViewPager in Android using Material TabLayout, ViewPager, and fragments — with full working Java code for each part. By the end, you will have a complete tabbed screen you can drop into any app.
What is Tabbed with ViewPager?
Tabbed with ViewPager is a UI pattern where two things work together:
- TabLayout — shows a strip of tabs at the top of the screen. The user taps a tab to switch content.
- ViewPager — holds multiple fragment pages. The user can also swipe left and right to move between them.
When you connect the two with setupWithViewPager(), they stay in sync. Tapping a tab swipes the pager. Swiping the pager highlights the correct tab. It feels seamless.
Each tab is backed by a fragment. The fragment defines what appears on that tab. So if you have three tabs — Chat, Contact, Call — you have three fragments, one for each tab.
This is a common pattern for apps where content is grouped into a few big categories. It is not the right choice for every screen, but for a small number of related sections, it works very well.
What the output looks like
Here is what you get at the end:
- A toolbar at the top with the app title
- Three tabs below the toolbar: Chat, Contact, Call
- A content area below the tabs showing the currently selected fragment
- Swipe left or right to change tabs, or tap a tab to jump directly
The three tab contents are simple — just a centered label. That makes it easy to see which tab is active. You can replace those with real content later.
Add the Material dependency
Open your app-level build.gradle file and add this line inside the dependencies block:
implementation 'com.google.android.material:material:1.1.0'
This library provides the Material TabLayout, the AppBarLayout, and other Material components. Version 1.1.0 is stable and widely used. You can use a newer version if your project supports it, but 1.1.0 works with most modern setups.
After adding the line, sync your Gradle project. If you skip this step, the com.google.android.material.tabs.TabLayout class will not be found and the code will not compile.
fragment_gallery.xml — the host layout
The host layout contains the toolbar, the TabLayout, and the ViewPager. Everything is wrapped in a vertical LinearLayout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
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="wrap_content">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="Whats App"
app:titleTextColor="#fff" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/mytab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextColor="#fff" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Let's look at the key parts:
- AppBarLayout — holds the toolbar and the tabs together so they scroll as one unit
- Toolbar — the top bar with the app title.
app:titleTextColor="#fff"makes the title white - TabLayout — the tab strip. The id
mytabis how we find it in code - ViewPager — the content area. The id
viewpageris how we connect it to the adapter
Note that the tab text color is also set to white, matching the title. This gives a clean look with the default Material toolbar background.
GalleryFragment.java — TabLayout + ViewPager
This is the main class that brings everything together. It inflates the layout, finds the TabLayout and ViewPager, sets up the adapter, and links the two with setupWithViewPager().
package com.example.mynavigation.ui.gallery;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.example.mynavigation.Call;
import com.example.mynavigation.Chat;
import com.example.mynavigation.Contact;
import com.example.mynavigation.R;
import com.google.android.material.tabs.TabLayout;
import java.util.ArrayList;
import java.util.List;
public class GalleryFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_gallery, container, false);
return root;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TabLayout tabs = view.findViewById(R.id.mytab);
ViewPager viewPager = view.findViewById(R.id.viewpager);
setUpViewPager(viewPager);
tabs.setupWithViewPager(viewPager);
}
private void setUpViewPager(ViewPager viewPager) {
MyTabs myTabs = new MyTabs(getActivity().getSupportFragmentManager());
myTabs.addTab(new Chat(), "Chat");
myTabs.addTab(new Contact(), "Contact");
myTabs.addTab(new Call(), "Call");
viewPager.setAdapter(myTabs);
}
class MyTabs extends FragmentPagerAdapter {
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public MyTabs(@NonNull FragmentManager fm) {
super(fm);
}
@NonNull
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
public void addTab(Fragment fragment, String title) {
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
}
}
Let's walk through what is happening:
onCreateView
Inflates the layout and returns the root view. This is standard for any fragment.
onViewCreated
After the view is created, we find the TabLayout and ViewPager by id. We call setUpViewPager() to attach the adapter. Then we call tabs.setupWithViewPager(viewPager) to connect the two — this is the line that makes the tabs and pager stay in sync.
setUpViewPager
Creates the adapter, adds three tabs (Chat, Contact, Call), and sets the adapter on the ViewPager.
MyTabs (the adapter)
Extends FragmentPagerAdapter and holds two lists — one for fragments, one for titles. The addTab method appends to both lists. getItem returns the fragment at a given position. getCount returns the total number of tabs. getPageTitle returns the title that TabLayout shows.
Note: we use FragmentPagerAdapter here. It keeps every fragment in memory, which is fine for a small number of tabs. If you have many tabs, switch to FragmentStatePagerAdapter to save memory.
The three tab fragments: Chat, Contact, Call
Each tab is backed by a simple fragment. They are almost identical — each inflates its own layout and returns the view. Here is Chat.java:
package com.example.mynavigation;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class Chat extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.chat, container, false);
}
}
Contact.java and Call.java are the same, just with R.layout.contact and R.layout.call instead.
Because the fragments do nothing except show a static layout, they are short. In a real app, each fragment would load data, handle clicks, and do its own work. The structure is the same — the fragment is the unit of content.
The tab layouts: chat.xml, contact.xml, call.xml
Each tab has its own simple layout. All three are identical except for the text. Here is chat.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Chat"
android:textSize="30sp"
android:layout_centerInParent="true"
android:gravity="center" />
</RelativeLayout>
contact.xml uses android:text="Contact" and call.xml uses android:text="Call". Everything else is the same.
The TextView is centered both horizontally and vertically because of layout_centerInParent="true" and gravity="center". The textSize="30sp" makes it big and easy to read so you can clearly see which tab you are on.
These layouts are intentionally simple. Replace the TextView with whatever content your app needs — a RecyclerView for chat messages, a contact list, a call log. The fragment structure stays the same.
Common questions
What is Tabbed with ViewPager in Android?
Tabbed with ViewPager in Android is a UI pattern where a TabLayout shows tabs at the top and a ViewPager swipes between fragments. Each tab is linked to a fragment, and swiping left or right moves between them.
What is the difference between TabLayout and ViewPager?
TabLayout shows the tab strip with titles and handles user taps. ViewPager manages the fragment pages and handles swipe gestures. They are connected with setupWithViewPager() so tapping a tab also swipes the pager and vice versa.
Which dependency is needed for TabLayout in Android?
You need the Material Components library. Add 'com.google.android.material:material:1.1.0' or a newer version to your app-level build.gradle dependencies.
What is FragmentPagerAdapter used for?
FragmentPagerAdapter is a ViewPager adapter that manages fragments. It keeps every fragment in memory, which is fine for a small number of tabs. Use FragmentStatePagerAdapter if you have many tabs and need to save memory.
How do I add a new tab to the ViewPager?
Call myTabs.addTab(new YourFragment(), "Tab Title") for each tab you want. The adapter stores the fragment and title in two lists and shows them in the order you added them.
Why do tabs appear in the wrong order?
Tab order comes from the order you call addTab(). If the tabs are out of order, check the sequence of addTab() calls. getItem(position) returns the fragment from that position in the list.
Where to go next
You now have a complete, working Tabbed with ViewPager screen in Android. You know the Gradle dependency, the host layout, the adapter pattern, the fragment classes, and the tab layouts.
If you remember only one thing, remember this: TabLayout handles the tabs, ViewPager handles the pages, and setupWithViewPager() keeps them in sync. Each tab is a fragment.
The real learning happens when you run this in Android Studio. Change the tab titles. Add a fourth tab. Replace the simple TextViews with real content. That is how the pattern becomes second nature.
If this helped, bookmark it. Next, try connecting the ViewPager to a BottomNavigationView instead of a TabLayout, or explore TabLayoutMediator — the modern replacement for the older setupWithViewPager() API.
1 comment:
thankstech update
tech update
tech update
Post a Comment