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));

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:
positionis the current page,positionOffsetgoes from 0 to 1 - When swiping left to right:
positionis the previous page,positionOffsetgoes 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 occurringSCROLL_STATE_DRAGGING: User is actively draggingSCROLL_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);

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);
}
}
}

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.
