Implementing and Customizing ViewPager in Android

ViewPager enables horizontal swiping between multiple screens in Android applications.

Basic ViewPager Implementation

Layout File

<androidx.viewpager.widget.ViewPager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Adapter Implementation

Create a custom adapter by extending PagerAdapter:

public class CustomPagerAdapter extends PagerAdapter {
    private List<View> pageViews = new ArrayList<>();

    public CustomPagerAdapter(Context context) {
        for (int i = 0; i < 4; i++) {
            TextView textView = (TextView) View.inflate(context, R.layout.page_text_layout, null);
            textView.setText("Page " + i);
            pageViews.add(textView);
        }
    }

    @Override
    public int getCount() {
        return pageViews.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(pageViews.get(position));
        return pageViews.get(position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(pageViews.get(position));
    }
}

Setting Up the Adapter

ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(new CustomPagerAdapter(this));

Basic ViewPager Demo

OnPageChangeListener

The OnPageChangeListener provides three callback methods for monitoring page changes:

onPageScrolled

public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
  • When swiping right to left: position is the current page, positionOffset goes from 0 to 1
  • When swiping left to right: position is the previous page, positionOffset goes from 1 to 0

onPageSelected

public void onPageSelected(int position)
  • Called when a new page becomes selected

onPageScrollStateChanged

public void onPageScrollStateChanged(int state)
  • SCROLL_STATE_IDLE: No scrolling is occurring
  • SCROLL_STATE_DRAGGING: User is actively dragging
  • SCROLL_STATE_SETTLING: Settling after user interaction

Implementing Infinite ViewPager

To create a looping ViewPager, add extra pages at the boundaries:

public class InfinitePagerAdapter extends PagerAdapter {
    private List<View> pageViews = new ArrayList<>();

    public InfinitePagerAdapter(Context context) {
        for (int i = 0; i < 4; i++) {
            TextView textView = (TextView) View.inflate(context, R.layout.page_text_layout, null);
            textView.setText("Page " + i);
            pageViews.add(textView);
        }
    }

    @Override
    public int getCount() {
        return pageViews.size() + 2;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View currentView;
        if (position == 0) {
            currentView = pageViews.get(pageViews.size() - 1);
        } else if (position == pageViews.size() + 1) {
            currentView = pageViews.get(0);
        } else {
            currentView = pageViews.get(position - 1);
        }
        
        try {
            container.addView(currentView);
        } catch (Exception e) {
            // Handle duplicate view addition
        }
        return currentView;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        // Skip view removal for infinite scrolling
    }
}

Boundary Handling

final ViewPager viewPager = findViewById(R.id.view_pager);
final PagerAdapter adapter = new InfinitePagerAdapter(this);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

    @Override
    public void onPageSelected(int position) {}

    @Override
    public void onPageScrollStateChanged(int state) {
        if (state == ViewPager.SCROLL_STATE_IDLE) {
            int currentPosition = viewPager.getCurrentItem();
            if (currentPosition == 0) {
                viewPager.setCurrentItem(adapter.getCount() - 2, false);
            } else if (currentPosition == adapter.getCount() - 1) {
                viewPager.setCurrentItem(1, false);
            }
        }
    }
});
viewPager.setCurrentItem(1);

Infinite ViewPager Demo

Custom Page Transitions with PageTransformer

Create custom animations by implementing PageTransformer:

private class CustomPageTransformer implements ViewPager.PageTransformer {
    @Override
    public void transformPage(View page, float position) {
        if (position < -1) {
            page.setAlpha(0);
        } else if (position <= 0) {
            page.setAlpha(1 + position);
        } else if (position < 1) {
            page.setTranslationX(-page.getWidth() * position);
            page.setScaleX(1 - position / 2);
            page.setScaleY(1 - position / 2);
            page.setAlpha(1 - position);
        } else {
            page.setAlpha(0);
        }
    }
}

Custom Transition Demo

Creating an Auto-Scrolling Banner

Implement an auto-scrolling banner with manual override capability:

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    private boolean isDragging = false;

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

    @Override
    public void onPageSelected(int position) {}

    @Override
    public void onPageScrollStateChanged(int state) {
        if (state == ViewPager.SCROLL_STATE_IDLE && isDragging) {
            handler.sendEmptyMessageDelayed(NEXT_PAGE, 3000);
            isDragging = false;
        } else if (state == ViewPager.SCROLL_STATE_DRAGGING) {
            handler.removeMessages(NEXT_PAGE);
            isDragging = true;
        }
    }
});

handler.sendEmptyMessageDelayed(NEXT_PAGE, 3000);

Handler Implementation

private static final int NEXT_PAGE = 1;

private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if (msg.what == NEXT_PAGE) {
            int currentItem = viewPager.getCurrentItem();
            if (++currentItem >= adapter.getCount()) {
                currentItem = 0;
            }
            viewPager.setCurrentItem(currentItem);
            handler.sendEmptyMessageDelayed(NEXT_PAGE, 3000);
        }
    }
};

Gallery Effect with ViewPager

Use the clipChildren property to create a gallery effect where adjacent pages are partially visible. For detailed implementation, refer to Android's clipChildren docmuentation.

Gallery Effect Demo

Tags: Android ViewPager UI Components PagerAdapter PageTransformer

Posted on Thu, 25 Jun 2026 17:14:48 +0000 by Christopher