Slide between fragments using ViewPager2

Try the Compose way
Jetpack Compose is the recommended UI toolkit for Android. Learn how to use Pager in Compose.

Screen slides are transitions from one entire screen to another and are common with UIs like setup wizards and slideshows. This topic shows you how to do screen slides with a ViewPager2 object. ViewPager2 objects can animate screen slides automatically. Here's an example of a screen slide that transitions from one screen of content to the next:

Figure 1. Screen slide animation.

If you want to jump ahead and see a full working example, view this sample app on GitHub.

To use ViewPager2, you need to add some AndroidX dependencies to your project. Then follow the steps outlined in the following sections.

Create the views

Create a layout file to use later for the content of a fragment. You also need to define a string for the contents of the fragment. The following example contains a text view that displays some text:

<!--fragment_screen_slide_page.xml-->
<ScrollViewxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextViewstyle="?android:textAppearanceMedium"
android:padding="16dp"
android:lineSpacingMultiplier="1.2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/lorem_ipsum"/>
</ScrollView>

Create the fragment

Create a Fragment class that returns the layout that you created in the onCreateView() method. You can then create instances of this fragment in the parent activity whenever you need a new page to display to the user:

Kotlin

importandroidx.fragment.app.Fragment
classScreenSlidePageFragment:Fragment(){
overridefunonCreateView(
inflater:LayoutInflater,
container:ViewGroup?,
savedInstanceState:Bundle?
):View=inflater.inflate(R.layout.fragment_screen_slide_page,container,false)
}

Java

importandroidx.fragment.app.Fragment;
...
publicclass ScreenSlidePageFragmentextendsFragment{
@Override
publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,
BundlesavedInstanceState){
return(ViewGroup)inflater.inflate(
R.layout.fragment_screen_slide_page,container,false);
}
}

Add a ViewPager2

ViewPager2 objects have built-in swipe gestures to transition through pages, and they display screen slide animations by default, so you don't need to create your own animation. ViewPager2 uses FragmentStateAdapter objects as a supply for new pages to display, so the FragmentStateAdapter uses the fragment class that you created.

To begin, create a layout that contains a ViewPager2 object:

<!--activity_screen_slide.xml-->
<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"/>

Create an activity that does the following:

  • Sets the content view to be the layout with the ViewPager2.
  • Creates a class that extends the FragmentStateAdapter abstract class and implements the createFragment() method to supply instances of ScreenSlidePageFragment as new pages. You must implement the getItemCount() method for the pager adapter, which returns the number of pages the adapter creates. There are five in the example.
  • Hooks up the FragmentStateAdapter to the ViewPager2 objects.

Kotlin

importandroidx.fragment.app.Fragment
importandroidx.fragment.app.FragmentActivity
...
/**
 * The number of pages (wizard steps) to show in this demo.
 */
privateconstvalNUM_PAGES=5
classScreenSlidePagerActivity:FragmentActivity(){
/**
 * The pager widget, which handles animation and allows swiping horizontally
 * to access previous and next wizard steps.
 */
privatelateinitvarviewPager:ViewPager2
overridefunonCreate(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_screen_slide)
// Instantiate a ViewPager2 and a PagerAdapter.
viewPager=findViewById(R.id.pager)
// The pager adapter, which provides the pages to the view pager widget.
valpagerAdapter=ScreenSlidePagerAdapter(this)
viewPager.adapter=pagerAdapter
}
overridefunonBackPressed(){
if(viewPager.currentItem==0){
// If the user is currently looking at the first step, allow the system to handle
// the Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed()
}else{
// Otherwise, select the previous step.
viewPager.currentItem=viewPager.currentItem-1
}
}
/**
 * A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in
 * sequence.
 */
privateinnerclassScreenSlidePagerAdapter(fa:FragmentActivity):FragmentStateAdapter(fa){
overridefungetItemCount():Int=NUM_PAGES
overridefuncreateFragment(position:Int):Fragment=ScreenSlidePageFragment()
}
}

Java

importandroidx.fragment.app.Fragment;
importandroidx.fragment.app.FragmentActivity;
...
publicclass ScreenSlidePagerActivityextendsFragmentActivity{
/**
 * The number of pages (wizard steps) to show in this demo.
 */
privatestaticfinalintNUM_PAGES=5;
/**
 * The pager widget, which handles animation and allows swiping horizontally to access previous
 * and next wizard steps.
 */
privateViewPager2viewPager;
/**
 * The pager adapter, which provides the pages to the view pager widget.
 */
privateFragmentStateAdapterpagerAdapter;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_slide);
// Instantiate a ViewPager2 and a PagerAdapter.
viewPager=findViewById(R.id.pager);
pagerAdapter=newScreenSlidePagerAdapter(this);
viewPager.setAdapter(pagerAdapter);
}
@Override
publicvoidonBackPressed(){
if(viewPager.getCurrentItem()==0){
// If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed();
}else{
// Otherwise, select the previous step.
viewPager.setCurrentItem(viewPager.getCurrentItem()-1);
}
}
/**
 * A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in
 * sequence.
 */
privateclass ScreenSlidePagerAdapterextendsFragmentStateAdapter{
publicScreenSlidePagerAdapter(FragmentActivityfa){
super(fa);
}
@Override
publicFragmentcreateFragment(intposition){
returnnewScreenSlidePageFragment();
}
@Override
publicintgetItemCount(){
returnNUM_PAGES;
}
}
}

Customize the animation using PageTransformer

To display a different animation from the default screen slide animation, implement the ViewPager2.PageTransformer interface and supply it to the ViewPager2 object. The interface exposes a single method, transformPage() . At each point in the screen's transition, this method is called once for each visible page—there's usually only one visible page—and for adjacent pages off the screen. For example, if page three is visible and the user drags towards page four, transformPage() is called for pages two, three, and four at each step of the gesture.

In your implementation of transformPage(), you can then create custom slide animations by determining which pages need to be transformed based on the position of the page on the screen. Obtain the page position from the position parameter of the transformPage() method.

The position parameter indicates where a given page is located relative to the center of the screen. This parameter is a dynamic property that changes as the user scrolls through a series of pages. When a page fills the screen, its position value is 0. When a page is drawn off the right side of the screen, its position value is 1. If the user scrolls halfway between pages one and two, page one has a position of -0.5, and page two has a position of 0.5. Based on the position of the pages on the screen, you can create custom slide animations by setting page properties with methods such as setAlpha() , setTranslationX() , or setScaleY() .

When you have an implementation of a PageTransformer , call setPageTransformer() with your implementation to apply your custom animations. For example, if you have a PageTransformer named ZoomOutPageTransformer, you can set your custom animations like this:

Kotlin

valviewPager:ViewPager2=findViewById(R.id.pager)
...
viewPager.setPageTransformer(ZoomOutPageTransformer())

Java

ViewPager2viewPager=findViewById(R.id.pager);
...
viewPager.setPageTransformer(newZoomOutPageTransformer());

See the Zoom-out page transformer and Depth page transformer sections for examples of a PageTransformer.

Zoom-out page transformer

This page transformer shrinks and fades pages when scrolling between adjacent pages. As a page gets closer to the center, it grows back to its normal size and fades in.

Figure 2. ZoomOutPageTransformer example.

Kotlin

privateconstvalMIN_SCALE=0.85f
privateconstvalMIN_ALPHA=0.5f
classZoomOutPageTransformer:ViewPager2.PageTransformer{
overridefuntransformPage(view:View,position:Float){
view.apply{
valpageWidth=width
valpageHeight=height
when{
position < -1->{// [-Infinity,-1)
// This page is way off-screen to the left.
alpha=0f
}
position<=1->{// [-1,1]
// Modify the default slide transition to shrink the page as well.
valscaleFactor=Math.max(MIN_SCALE,1-Math.abs(position))
valvertMargin=pageHeight*(1-scaleFactor)/2
valhorzMargin=pageWidth*(1-scaleFactor)/2
translationX=if(position < 0){
horzMargin-vertMargin/2
}else{
horzMargin+vertMargin/2
}
// Scale the page down (between MIN_SCALE and 1).
scaleX=scaleFactor
scaleY=scaleFactor
// Fade the page relative to its size.
alpha=(MIN_ALPHA+
(((scaleFactor-MIN_SCALE)/(1-MIN_SCALE))*(1-MIN_ALPHA)))
}
else->{// (1,+Infinity]
// This page is way off-screen to the right.
alpha=0f
}
}
}
}
}

Java

publicclass ZoomOutPageTransformerimplementsViewPager2.PageTransformer{
privatestaticfinalfloatMIN_SCALE=0.85f;
privatestaticfinalfloatMIN_ALPHA=0.5f;
publicvoidtransformPage(Viewview,floatposition){
intpageWidth=view.getWidth();
intpageHeight=view.getHeight();
if(position < -1){// [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0f);
}elseif(position<=1){// [-1,1]
// Modify the default slide transition to shrink the page as well.
floatscaleFactor=Math.max(MIN_SCALE,1-Math.abs(position));
floatvertMargin=pageHeight*(1-scaleFactor)/2;
floathorzMargin=pageWidth*(1-scaleFactor)/2;
if(position < 0){
view.setTranslationX(horzMargin-vertMargin/2);
}else{
view.setTranslationX(-horzMargin+vertMargin/2);
}
// Scale the page down (between MIN_SCALE and 1).
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
// Fade the page relative to its size.
view.setAlpha(MIN_ALPHA+
(scaleFactor-MIN_SCALE)/
(1-MIN_SCALE)*(1-MIN_ALPHA));
}else{// (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0f);
}
}
}

Depth page transformer

This page transformer uses the default slide animation for sliding pages to the left, while using a "depth" animation for sliding pages to the right. This depth animation fades the page out and scales it down linearly.

Figure 3. DepthPageTransformer example.

During the depth animation, the default animation (a screen slide) still takes place, so you must counteract the screen slide with a negative X translation. For example:

Kotlin

view.translationX=-1*view.width*position

Java

view.setTranslationX(-1*view.getWidth()*position);

The following example shows how to counteract the default screen slide animation in a working page transformer:

Kotlin

privateconstvalMIN_SCALE=0.75f
@RequiresApi(21)
classDepthPageTransformer:ViewPager2.PageTransformer{
overridefuntransformPage(view:View,position:Float){
view.apply{
valpageWidth=width
when{
position < -1->{// [-Infinity,-1)
// This page is way off-screen to the left.
alpha=0f
}
position<=0->{// [-1,0]
// Use the default slide transition when moving to the left page.
alpha=1f
translationX=0f
translationZ=0f
scaleX=1f
scaleY=1f
}
position<=1->{// (0,1]
// Fade the page out.
alpha=1-position
// Counteract the default slide transition.
translationX=pageWidth*-position
// Move it behind the left page.
translationZ=-1f
// Scale the page down (between MIN_SCALE and 1).
valscaleFactor=(MIN_SCALE+(1-MIN_SCALE)*(1-Math.abs(position)))
scaleX=scaleFactor
scaleY=scaleFactor
}
else->{// (1,+Infinity]
// This page is way off-screen to the right.
alpha=0f
}
}
}
}
}

Java

@RequiresApi(21)
publicclass DepthPageTransformerimplementsViewPager2.PageTransformer{
privatestaticfinalfloatMIN_SCALE=0.75f;
publicvoidtransformPage(Viewview,floatposition){
intpageWidth=view.getWidth();
if(position < -1){// [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0f);
}elseif(position<=0){// [-1,0]
// Use the default slide transition when moving to the left page.
view.setAlpha(1f);
view.setTranslationX(0f);
view.setTranslationZ(0f);
view.setScaleX(1f);
view.setScaleY(1f);
}elseif(position<=1){// (0,1]
// Fade the page out.
view.setAlpha(1-position);
// Counteract the default slide transition.
view.setTranslationX(pageWidth*-position);
// Move it behind the left page
view.setTranslationZ(-1f);
// Scale the page down (between MIN_SCALE and 1).
floatscaleFactor=MIN_SCALE
+(1-MIN_SCALE)*(1-Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
}else{// (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0f);
}
}
}

Additional resources

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

Samples

Videos

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2026年05月28日 UTC.