Android & Kotlin

ViewPager2 with TabLayout Android Example

Pinterest LinkedIn Tumblr

In this post, we’ll learn about ViewPager2, what is it? how does work? For doing this we’ll create a sample app that contains ViewPager2 with TabLayout in Android. So lets started

What is ViewPager2

ViewPager2 is an Android widget that allows us to change the screen with changing activity with a swipeable feature. Recently, Google IO was released beta04 version ViewPager2. ViewPager2 is the replacement of ViewPager, It’s well optimized, smarter and efficient.

How does work?

ViewPager2 has a variety of new features. the most important feature is that ViewPager2 is built on RecyclerView component. So you can add or remove fragment dynamically. Basically, PagerAdapter is replaced by RecyclerView.Adapter and FragmentStatePagerAdapter is replaced by FragmentStateAdapter. So it’s easy to maintainable and scalable.

In this article, I’m focusing on ViewPager2 implementation only. For more details, I will write a separate article on ViewPager2.

Step of implantation ViewPager2 with TabLayout

  • Project creation and adding dependencies
  • Add needed resource in the directory
  • Prepare layout with ViewPager2 and TabLayout
  • Create Fragment with Layout
  • Prepare FragmentStateAdapter
  • Finally, set the adapter on ViewPager2
ViewPager2 with TabLayout (Demo App)

1. Project creation and adding dependencies

Let’s open Android Studio and create fresh project with a default template (such as EmptyActivity with androidx). Once project sync completed open the project app/build.gradle and add following dependencies

  implementation 'androidx.viewpager2:viewpager2:1.0.0-beta04'
  implementation 'androidx.fragment:fragment-ktx:1.2.0-alpha04'
  implementation 'com.google.android.material:material:1.1.0-alpha10'

2. Add needed resource in the directory

Open color.xml resource file nd adds below code.

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <color name="colorPrimary">#008577</color>
  <color name="colorPrimaryDark">#00574B</color>
  <color name="colorAccent">#D81B60</color>

  <color name="red_100">#F44336</color>
  <color name="red_300">#3F51B5</color>
  <color name="red_500">#9C27B0</color>
  <color name="red_700">#2196F3</color>
  <color name="blue_100">#00BCD4</color>
  <color name="blue_300">#7BAAF7</color>
  <color name="blue_500">#009688</color>
  <color name="blue_700">#3367D6</color>
  <color name="green_100">#CDDC39</color>
  <color name="green_300">#57BB8A</color>
  <color name="green_500">#673AB7</color>
  <color name="green_700">#0B8043</color>

</resources>

3. Prepare layout with ViewPager2 and TabLayout

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:background="#FFFFFF"
    >

  <com.google.android.material.tabs.TabLayout
      android:id="@+id/tabs"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      app:tabMode="scrollable"
      />

  <androidx.viewpager2.widget.ViewPager2
      android:id="@+id/view_pager"
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:layout_weight="1"
      />

</LinearLayout>

4. Create Fragment with Layout

In this sample app, I’m using a single fragment you can use based on need. Let’s create a fragment with the layout .

4.1 open the layout file and paste below code
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CardFragment"
    >

  <TextView
      android:id="@+id/tv_counter"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:gravity="center"
      android:textColor="#fff"
      android:textSize="20sp"
      android:textStyle="bold"
      tools:text="@string/hello_blank_fragment"
      />

</FrameLayout>
4.2 Now bind the view with Fragment file just like below
package com.viewpager2example;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link CardFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class CardFragment extends Fragment {

  private static final String ARG_COUNT = "param1";
  private Integer counter;

  private int[] COLOR_MAP = {
      R.color.red_100, R.color.red_300, R.color.red_500, R.color.red_700, R.color.blue_100,
      R.color.blue_300, R.color.blue_500, R.color.blue_700, R.color.green_100, R.color.green_300,
      R.color.green_500, R.color.green_700
  };

  public CardFragment() {
    // Required empty public constructor
  }

  public static CardFragment newInstance(Integer counter) {
    CardFragment fragment = new CardFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_COUNT, counter);
    fragment.setArguments(args);
    return fragment;
  }

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
      counter = getArguments().getInt(ARG_COUNT);
    }
  }

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
      Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_card, container, false);
  }

  @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    view.setBackgroundColor(ContextCompat.getColor(getContext(), COLOR_MAP[counter]));
    TextView textViewCounter = view.findViewById(R.id.tv_counter);
    textViewCounter.setText("Fragment No " + (counter+1));
  }
}

5. Prepare FragmentStateAdapter

package com.viewpager2example;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;

public class ViewPagerAdapter extends FragmentStateAdapter {
  private static final int CARD_ITEM_SIZE = 10;

  public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
    super(fragmentActivity);
  }

  @NonNull @Override public Fragment createFragment(int position) {
    return CardFragment.newInstance(position);
  }

  @Override public int getItemCount() {
    return CARD_ITEM_SIZE;
  }
}

6. Finally, set the adapter on ViewPager2

package com.viewpager2example;

import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;

public class MainActivity extends AppCompatActivity {

  TabLayout tabLayout;
  ViewPager2 viewPager;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    viewPager = findViewById(R.id.view_pager);
    tabLayout = findViewById(R.id.tabs);

    viewPager.setAdapter(createCardAdapter());
    new TabLayoutMediator(tabLayout, viewPager,
        new TabLayoutMediator.TabConfigurationStrategy() {
          @Override public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
            tab.setText("Tab " + (position + 1));
          }
        }).attach();
  }

  private ViewPagerAdapter createCardAdapter() {
    ViewPagerAdapter adapter = new ViewPagerAdapter(this);
    return adapter;
  }
}

Conclusion

In this android app example, we have learned the implementation of ViewPager2 with TabLayout. I hope it’s helpful for you.

Keep in touch

If you want to keep in touch and get an email when I write new blog posts, follow me on facebook or subscribe to usIt only takes about 10 seconds to register. 

Still, if you have any queries please put your comment below.

11 Comments

  1. How to make it save the chosen tab? If I choose tab5 and press back, I want tab5 to be chosen when I go back to this app. But tab1 is always chosen at the start.

  2. Thanks, very useful example, you explained a complex topic in simple words

  3. Raimund Popp Reply

    if the fragmentadapter should load different fragments and not count up the same side, then it does not work.

    @NonNull @Override public Fragment createFragment(int position) {
        Fragment page_fragment=null;
    
        switch (position) {
            case 0:
                page_fragment= new page1();
                break;
            case 1:
                page_fragment= new page2();
                break;
            default:
                page_fragment= new pageDefault();
                break;
        }
    
    
  4. Ali hassan Reply

    how can we change the tab on click. i know its works fine with swapping but not on click

  5. Thank you. If I have three fragment and a tablayout with 3 tabs how can I bind I together following this tutorial?

  6. Thanks a lot!!!! This tutorial helped me a lot!! You saved my project!!

  7. Jayesh Agwan Reply

    Thanks for tutorial. Very helpful and solved my issue. I want to show only 2 tabs. How can I restrict ?

  8. Robert Wang Reply

    Thank you so much. I had trouble importing tabLayoutMediator but the dependency version here works.

  9. Sajjad Akbari Reply

    Thank you very much.
    You The Besttttttt !!

    Please make a tutorial for fmod voice changer and control it like play / stop / save / progress bar and …

    Thank you.

Write A Comment