This tutorial shows how to implement a TabLayout with a ViewPager using Java in Android Studio. This pattern is widely used for creating swipeable tabs in Android apps.
1. Add Required Dependencies (Optional)
Make sure you have these in your build.gradle
(app-level):
implementation 'com.google.android.material:material:1.12.0'
Sync your project after adding.
2. Add TabLayout and ViewPager in activity_main
Open res/layout/activity_main.xml
and update it:

<?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:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <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>
3. Create Fragment Layouts
Create two fragments:
HomeFragment.java
ProfileFragment.java
Each should inflate a layout (e.g., fragment_home.xml
and fragment_profile.xml
).

HomeFragment.java:
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 HomeFragment extends Fragment { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_home, container, false); } }
fragment_home.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <TextView android:text="Welcome to Home" android:textSize="24sp" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
4. Create a ViewPagerAdapter

public class ViewPagerAdapter extends FragmentPagerAdapter { private final List<Fragment> fragmentList = new ArrayList<>(); private final List<String> fragmentTitleList = new ArrayList<>(); public ViewPagerAdapter(FragmentManager fm) { super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); } @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); } @Nullable @Override public CharSequence getPageTitle(int position) { return fragmentTitleList.get(position); } }
6. Setup ViewPager and TabLayout in MainActivity

import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager.widget.ViewPager; 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 HomeFragment(), "Tab 1"); adapter.addFragment(new ProfileFragment(), "Tab 2"); viewPager.setAdapter(adapter); tabLayout.setupWithViewPager(viewPager); } }
Output

- A working TabLayout with two tabs.
- Each tab shows a different Fragment.
- Users can swipe between tabs or tap on them.
Tips
- You can use
ViewPager2
for a newer implementation. - Add icons with
tabLayout.getTabAt(index).setIcon(R.drawable.icon);
- You can use