[`ViewPager2`](https://developer.android.com/jetpack/androidx/releases/viewpager2)is an improved version of the`ViewPager`library that offers enhanced functionality and addresses common difficulties with using`ViewPager`. If your app already uses`ViewPager`, read this page to learn more about migrating to`ViewPager2`.

If you want to use`ViewPager2`in your app and are not currently using`ViewPager`, read[Slide between fragments using ViewPager2](https://developer.android.com/training/animation/screen-slide-2)and[Create swipe views with tabs using ViewPager2](https://developer.android.com/guide/navigation/navigation-swipe-view-2)for more information.

## Benefits of migrating to ViewPager2

The primary reason to migrate is that`ViewPager2`is receiving active development support and`ViewPager`is not. However,`ViewPager2`also offers several other specific advantages.

### Vertical orientation support

`ViewPager2`supports vertical paging in addition to traditional horizontal paging. You can enable vertical paging for a`ViewPager2`element by setting its`android:orientation`attribute:  

    <androidx.viewpager2.widget.ViewPager2
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:orientation="vertical" />

You can also set this attribute programmatically using the[setOrientation()](https://developer.android.com/reference/kotlin/androidx/viewpager2/widget/ViewPager2#setorientation)method.

### Right-to-left support

`ViewPager2`supports right-to-left (RTL) paging. RTL paging is enabled automatically where appropriate based on locale, but you can also manually enable RTL paging for a`ViewPager2`element by setting its`android:layoutDirection`attribute:  

    <androidx.viewpager2.widget.ViewPager2
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:layoutDirection="rtl" />

You can also set this attribute programmatically using the[setLayoutDirection()](https://developer.android.com/reference/kotlin/android/view/View#setlayoutdirection)method.

### Modifiable fragment collections

`ViewPager2`supports paging through a modifiable collection of fragments, calling[`notifyDatasetChanged()`](https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/RecyclerView.Adapter#notifydatasetchanged)to update the UI when the underlying collection changes.

This means that your app can dynamically modify the fragment collection at runtime, and`ViewPager2`will correctly display the modified collection.

### DiffUtil

`ViewPager2`is built on[`RecyclerView`](https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/RecyclerView), which means it has access to the[`DiffUtil`](https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/DiffUtil)utility class. This results in several benefits, but most notably it means that`ViewPager2`objects natively take advantage of the dataset change animations from the`RecyclerView`class.

## Migrate your app to ViewPager2

Follow these steps to update`ViewPager`objects in your app to`ViewPager2`:

### Update XML layout files

First, replace the`ViewPager`elements in your XML layout files with`ViewPager2`elements:  

    <!-- A ViewPager element -->
    <android.support.v4.view.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- A ViewPager2 element -->
    <androidx.viewpager2.widget.ViewPager2
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

### Update adapter classes

When using`ViewPager`, you had to extend the adapter class that supplied new pages to the object. Depending on the use case,`ViewPager`used three different abstract classes.`ViewPager2`only uses two abstract classes.

For each`ViewPager`object you are converting to a`ViewPager2`object, update the adapter class to extend the appropriate abstract class as follows:

- When`ViewPager`used[`PagerAdapter`](https://developer.android.com/reference/kotlin/androidx/viewpager/widget/PagerAdapter)to page through views, use[`RecyclerView.Adapter`](https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/RecyclerView.Adapter)with`ViewPager2`.
- When`ViewPager`used[`FragmentPagerAdapter`](https://developer.android.com/reference/kotlin/androidx/fragment/app/FragmentPagerAdapter)to page through a small, fixed number of fragments, use[`FragmentStateAdapter`](https://developer.android.com/reference/kotlin/androidx/viewpager2/adapter/FragmentStateAdapter)with`ViewPager2`.
- When`ViewPager`used[`FragmentStatePagerAdapter`](https://developer.android.com/reference/kotlin/androidx/fragment/app/FragmentStatePagerAdapter)to page through a large or unknown number of fragment, use[`FragmentStateAdapter`](https://developer.android.com/reference/kotlin/androidx/viewpager2/adapter/FragmentStateAdapter)with`ViewPager2`.

#### Constructor parameters

Fragment-based adapter classes inheriting from`FragmentPagerAdapter`or`FragmentStatePagerAdapter`always accept a single[`FragmentManager`](https://developer.android.com/reference/kotlin/androidx/fragment/app/FragmentManager)object as a constructor parameter. When you extend`FragmentStateAdapter`for a`ViewPager2`adapter class, you have the following options for constructor parameters instead:

- The[`FragmentActivity`](https://developer.android.com/reference/kotlin/androidx/fragment/app/FragmentActivity)object or[`Fragment`](https://developer.android.com/reference/kotlin/androidx/fragment/app/Fragment)object where the`ViewPager2`object resides. In most cases, this is the better option.
- A`FragmentManager`object and a[`Lifecycle`](https://developer.android.com/reference/kotlin/androidx/lifecycle/Lifecycle)object.

View-based adapter classes inheriting directly from`RecyclerView.Adapter`do not require a constructor parameter.

#### Override methods

Your adapter classes also need to override different methods for`ViewPager2`than they did for`ViewPager`:

- Instead of`getCount()`, override[`getItemCount()`](https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/RecyclerView.Adapter#getitemcount). Other than the name, this method is unchanged.
- Instead of`getItem()`, override[`createFragment()`](https://developer.android.com/reference/kotlin/androidx/viewpager2/adapter/FragmentStateAdapter#createfragment)in fragment-based adapter classes. Make sure that your new`createFragment()`method always supplies a new fragment instance each time the function is called instead of reusing instances.

| **Note:** The[`DiffUtil`](https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/DiffUtil)utility class relies on identifying items by ID. If you are using`ViewPager2`to page through a mutable collection, you must also override[`getItemId()`](https://developer.android.com/reference/kotlin/androidx/viewpager2/adapter/FragmentStateAdapter#getitemid)and[`containsItem()`](https://developer.android.com/reference/kotlin/androidx/viewpager2/adapter/FragmentStateAdapter#containsitem).  
| Additionally, The[`getPageWidth()`](https://developer.android.com/reference/kotlin/androidx/viewpager/widget/PagerAdapter#getpagewidth)method is not supported for use with`ViewPager2`. If you currently use`getPageWidth()`with`ViewPager`to enable peeking on adjacent pages, you must instead use the[`clipToPadding`](https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/RecyclerView#getcliptopadding)attribute of`RecyclerView`as demonstrated in the[sample app](https://github.com/android/views-widgets-samples/blob/87e58d1c6d0c832c5b362d33390148679182d314/ViewPager2/app/src/main/java/androidx/viewpager2/integration/testapp/PreviewPagesActivity.kt).

#### Summary

In summary, to convert a`ViewPager`adapter class for use with`ViewPager2`, you must make the following changes:

1. Change the superclass to`RecyclerView.Adapter`for paging through views, or`FragmentStateAdapter`for paging through fragments.
2. Change the constructor parameters in fragment-based adapter classes.
3. Override`getItemCount()`instead of`getCount()`.
4. Override`createFragment()`instead of`getItem()`in fragment-based adapter classes.

### Kotlin

```kotlin
// A simple ViewPager adapter class for paging through fragments
class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
    override fun getCount(): Int = NUM_PAGES

    override fun getItem(position: Int): Fragment = ScreenSlidePageFragment()
}

// An equivalent ViewPager2 adapter class
class ScreenSlidePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
    override fun getItemCount(): Int = NUM_PAGES

    override fun createFragment(position: Int): Fragment = ScreenSlidePageFragment()
}
```

### Java

```java
// A simple ViewPager adapter class for paging through fragments
public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
    public ScreenSlidePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return new ScreenSlidePageFragment();
    }

    @Override
    public int getCount() {
        return NUM_PAGES;
    }
}

// An equivalent ViewPager2 adapter class
private class ScreenSlidePagerAdapter extends FragmentStateAdapter {
    public ScreenSlidePagerAdapter(FragmentActivity fa) {
        super(fa);
    }

    @Override
    public Fragment createFragment(int position) {
        return new ScreenSlidePageFragment();
    }

    @Override
    public int getItemCount() {
        return NUM_PAGES;
    }
}
```

### Refactor TabLayout interfaces

`ViewPager2`introduces changes to[`TabLayout`](https://developer.android.com/reference/com/google/android/material/tabs/TabLayout)integration. If you currently use a`ViewPager`with a`TabLayout`object to display horizontal tabs for navigation, you need to refactor the`TabLayout`object for integration with`ViewPager2`.

`TabLayout`has been decoupled from`ViewPager2`and is now available as part of[Material components](https://developer.android.com/guide/topics/ui/look-and-feel). This means that in order to use it, you need to add the appropriate dependency to your`build.gradle`file:  

### Groovy

```groovy
implementation "com.google.android.material:material:1.1.0-beta01"
```

### Kotlin

```kotlin
implementation("com.google.android.material:material:1.1.0-beta01")
```

You also need to change the`TabLayout`element's location in the hierarchy of your XML layout file. With`ViewPager`, the`TabLayout`element is declared as a child of the`ViewPager`element; but with`ViewPager2`, the`TabLayout`element is declared directly above the`ViewPager2`element, on the same level:  

    <!-- A ViewPager element with a TabLayout -->
    <androidx.viewpager.widget.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

    </androidx.viewpager.widget.ViewPager>

    <!-- A ViewPager2 element with a TabLayout -->
    <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.tabs.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

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

    </LinearLayout>

Finally, you must update the code that attaches the`TabLayout`object to the`ViewPager`object. While`TabLayout`uses its own[`setupWithViewPager()`](https://developer.android.com/reference/com/google/android/material/tabs/TabLayout#setupwithviewpager)method to integrate with`ViewPager`, it requires a[`TabLayoutMediator`](https://developer.android.com/reference/com/google/android/material/tabs/TabLayoutMediator)instance to integrate with`ViewPager2`.

The`TabLayoutMediator`object also handles the task of generating page titles for the`TabLayout`object, which means that the adapter class does not need to override`getPageTitle()`:  

### Kotlin

```kotlin
// Integrating TabLayout with ViewPager
class CollectionDemoFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val tabLayout = view.findViewById(R.id.tab_layout)
        tabLayout.setupWithViewPager(viewPager)
    }
    ...
}

class DemoCollectionPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {

    override fun getCount(): Int  = 4

    override fun getPageTitle(position: Int): CharSequence {
        return "OBJECT ${(position + 1)}"
    }
    ...
}

// Integrating TabLayout with ViewPager2
class CollectionDemoFragment : Fragment() {
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val tabLayout = view.findViewById(R.id.tab_layout)
        TabLayoutMediator(tabLayout, viewPager) { tab, position ->
            tab.text = "OBJECT ${(position + 1)}"
        }.attach()
    }
    ...
}
```

### Java

```java
// Integrating TabLayout with ViewPager
public class CollectionDemoFragment extends Fragment {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        TabLayout tabLayout = view.findViewById(R.id.tab_layout);
        tabLayout.setupWithViewPager(viewPager);
    }
    ...
}

public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter {
    ...
    @Override
    public int getCount() {
        return 4;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "OBJECT " + (position + 1);
    }
    ...
}

// Integrating TabLayout with ViewPager2
public class CollectionDemoFragment : Fragment() {
    ...
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        TabLayout tabLayout = view.findViewById(R.id.tab_layout);
        new TabLayoutMediator(tabLayout, viewPager,
                (tab, position) -> tab.setText("OBJECT " + (position + 1))
        ).attach();
    }
    ...
}
```

### Support nested scrollable elements

`ViewPager2`does not natively support nested scroll views in cases where the scroll view has the same orientation as the`ViewPager2`object that contains it. For example, scrolling would not work for a vertical scroll view inside a vertically-oriented`ViewPager2`object.

To support a scroll view inside a`ViewPager2`object with the same orientation, you must call[`requestDisallowInterceptTouchEvent()`](https://developer.android.com/reference/android/view/ViewGroup#requestDisallowInterceptTouchEvent(boolean))on the`ViewPager2`object when you expect to scroll the nested element instead. The[ViewPager2 nested scrolling sample](https://github.com/android/views-widgets-samples/blob/master/ViewPager2/app/src/main/res/layout/item_nested_recyclerviews.xml#L43)demonstrates one way of solving this problem with a versatile[custom wrapper layout](https://github.com/android/views-widgets-samples/blob/master/ViewPager2/app/src/main/java/androidx/viewpager2/integration/testapp/NestedScrollableHost.kt).

## Additional resources

To learn more about`ViewPager2`, see the following additional resources.

### Samples

- [ViewPager2 samples](https://goo.gle/viewpager2-sample)on GitHub

### Videos

- [Turning the Page: Migrating to ViewPager2](https://www.youtube.com/watch?v=lAP6cz1HSzA)(Android Dev Summit '19)