Start an Android ViewPager at a Fractional Position

Android’s ViewPager (and ViewPager2) is designed to work with integer-based page indices. By default, it always starts at position 0, representing the first page. However, in modern UI designs—such as carousels, card sliders, or preview-based layouts—developers often want the pager to start partially scrolled, for example at 0.5, so the first item appears centered or partially visible.

Since ViewPager does not natively support fractional start positions, achieving this effect requires a controlled workaround. This article explains why this limitation exists, and provides robust, production-ready techniques to simulate a fractional starting position like 0.5.


Why ViewPager Does Not Support Fractional Positions

Internally, ViewPager operates using:

  • Integer page indices
  • Fixed page widths (fractions are applied per page, not per position)
  • Scroll offsets computed relative to the current page

As a result:

  • setCurrentItem() only accepts integers
  • There is no API like setCurrentItem(0.5f)

To solve this, we must combine adapter configuration + manual scrolling.


Recommended Strategy (Stable & Production-Safe)

The most reliable approach is a two-step initialization:

  1. Start at an integer page
  2. Manually scroll by a fractional offset (e.g. 50% of page width)

This method works with:

  • Standard ViewPager
  • Infinite / looping adapters
  • Custom PageTransformers
  • Carousel layouts

Step 1: Configure Page Width (Optional but Recommended)

If you are building a carousel (e.g. 3 items visible), override getPageWidth() in your adapter.

override fun getPageWidth(position: Int): Float {
    return 1f / 3f // 3 items visible
}

This ensures predictable geometry when applying a fractional offset.


Step 2: Set the Initial Integer Position

Set the ViewPager to an integer position without animation.

carouselViewPager.setCurrentItem(startPosition, false)

For infinite carousels, startPosition is usually a large number centered around your dataset.


Step 3: Apply a Fractional Offset (0.5 Page)

Once the ViewPager is laid out, apply a horizontal scroll equal to half a page width.

carouselViewPager.post {
    val pageWidth = carouselViewPager.width / 3 // adjust to your page width logic
    val halfPageOffset = pageWidth / 2

    carouselViewPager.scrollBy(halfPageOffset, 0)
}

Why post {} Is Required

  • ViewPager width is only known after layout
  • Calling scrollBy() earlier will have no effect

Result

Visually, the ViewPager now appears to start at position 0.5:

  • The first page is centered or partially visible
  • Neighboring pages are previewed
  • Swipe behavior remains natural

Alternative: Using Padding Instead of scrollBy

In some carousel designs, you can simulate a fractional start by applying padding:

carouselViewPager.apply {
    clipToPadding = false
    setPadding(width / 6, 0, width / 6, 0)
}

This works well for static previews, but is less precise than scrollBy().


ViewPager2 Considerations

With ViewPager2, the same idea applies, but you must access the internal RecyclerView:

val recyclerView = carouselViewPager.getChildAt(0) as RecyclerView

recyclerView.post {
    val offset = recyclerView.width / 6
    recyclerView.scrollBy(offset, 0)
}

This approach is safe and officially supported.


Common Pitfalls to Avoid

❌ Calling scrollTo() before layout
❌ Trying to use fractional values in setCurrentItem()
❌ Forgetting to disable clipToPadding for carousels
❌ Applying offset before adapter is attached


Best Practices Summary

RequirementRecommendation
Fractional startUse scrollBy()
Infinite carouselStart from large index
Multiple visible pagesOverride getPageWidth()
Smooth UXDisable animation on initial set
CompatibilityUse post {}

Conclusion

Although Android’s ViewPager does not support fractional start positions natively, a clean and maintainable solution exists. By combining:

  • Integer-based initialization
  • Manual pixel offset scrolling
  • Optional page width control

you can achieve a 0.5 start position (or any fractional offset) that works seamlessly with carousels, infinite pagers, and complex UI animations.

This approach is widely used in production apps and remains compatible with custom transformers, ViewModels, and synchronized pagers.

This article is inspired by real-world challenges we tackle in our projects. If you're looking for expert solutions or need a team to bring your idea to life,

Let's talk!

    Please fill your details, and we will contact you back

      Please fill your details, and we will contact you back