Dots Indicator: Four Animation Styles for Android ViewPager and Jetpack Compose
Dots indicators for Android ViewPager and Compose
At a glance
- What is it?
- Dots Indicator (com.tbuonomo:dotsindicator) is an Android library that adds animated page position indicators to Jetpack Compose and XML-based ViewPager or ViewPager2 controls. Version 5.1.1 ships four named animation types from a single Maven Central artifact.
- Who is it for?
- Dots Indicator is the right choice for Android teams that need a drop-in pager dot indicator with a visible animation style and support for both Jetpack Compose and legacy XML views in the same dependency. The four built-in types cover the most common animation patterns, and the library was last pushed on 2026-08-31.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 31 days ago.
- What is it written in?
- Mainly Kotlin, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Dots Indicator Solves and Who Needs It
Android's ViewPager2 and Compose's horizontal pager provide no built-in page position indicator. An indicator showing which page is current is standard UI for onboarding flows, image carousels, and feature tours. Writing one from scratch requires custom drawing code and listener plumbing.
Dots Indicator is an Android library that provides this component with four pre-built animation types. It handles the listener attachment internally through an attachTo() method for XML views and connects directly to a Compose PagerState. The library supports ViewPager (the legacy type) and ViewPager2 through the same attachTo() call, so projects migrating from one to the other do not need to change the indicator code.
Adding the Dependency from Maven Central
The library ships as a single artifact on Maven Central. Add the repositories block and the implementation dependency to your build.gradle.kts:
repositories {
google()
mavenCentral()
}
dependencies {
implementation("com.tbuonomo:dotsindicator:5.1.1")
}Both the Compose and XML APIs are included in this one artifact. No separate dependency is needed for Compose support.
Four Animation Types in Jetpack Compose
In Compose, the DotsIndicator composable takes a dotCount, a type, and a pagerState. The four types are:
ShiftIndicatorType: the selected dot expands horizontally, shifting the adjacent dots apart. Configure the dot color through DotGraphic.
SpringIndicatorType: a spring physics animation moves the indicator between dots. DotGraphic controls the ring dots (border-only style) and selectorDotGraphic controls the moving filled dot:
DotsIndicator(
dotCount = pageCount,
type = SpringIndicatorType(
dotsGraphic = DotGraphic(
size = 16.dp,
borderWidth = 2.dp,
borderColor = MaterialTheme.colorScheme.primary,
color = Color.Transparent
),
selectorDotGraphic = DotGraphic(
size = 14.dp,
color = MaterialTheme.colorScheme.primary
)
),
pagerState = pagerState
)WormIndicatorType: the selected indicator stretches like a worm between dot positions.
BalloonIndicatorType: a dot grows to a larger size on the active position. The balloonSizeFactor parameter controls the growth multiplier. The README shows this configuration:
DotsIndicator(
dotCount = pageCount,
type = BalloonIndicatorType(
dotsGraphic = DotGraphic(
size = 8.dp,
color = MaterialTheme.colorScheme.primary
),
balloonSizeFactor = 2f
),
dotSpacing = 20.dp,
pagerState = pagerState
)Note that the dotSpacing parameter on the composable itself (separate from DotGraphic) is set here to 20.dp to accommodate the balloon's larger selected-state size.
XML Layout Integration for ViewPager and ViewPager2
For projects using XML layouts, each indicator type has a corresponding View class: DotsIndicator, SpringDotsIndicator, and WormDotsIndicator. Declare one in your layout XML:
<com.tbuonomo.viewpagerdotsindicator.DotsIndicator
android:id="@+id/dots_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:dotsColor="@color/material_white"
app:dotsSize="16dp"
app:dotsSpacing="4dp"
app:dotsWidthFactor="2.5"
app:selectedDotColor="@color/md_blue_200"
app:progressMode="true"
app:dotsClickable="true" />Then attach it to the pager in Kotlin:
val dotsIndicator = findViewById<DotsIndicator>(R.id.dots_indicator)
val viewPager = findViewById<ViewPager2>(R.id.view_pager)
viewPager.adapter = ViewPagerAdapter()
dotsIndicator.attachTo(viewPager)The attachTo() method accepts both ViewPager and ViewPager2 with no difference in call syntax:
dotsIndicator.attachTo(viewPager)
dotsIndicator.attachTo(viewPager2)The SpringDotsIndicator and WormDotsIndicator classes follow the same pattern in Kotlin: find the view, find the pager, set the adapter, and call attachTo().
Customization: DotGraphic Parameters and XML Attributes
In Compose, DotGraphic controls the appearance of each dot through size (as Dp), color, borderWidth, and borderColor. The SpringIndicatorType has two DotGraphic instances: one for the background ring dots and one for the moving selector dot, which lets you set different sizes for each.
In XML, the equivalent attributes are dotsSize (default 16dp), dotsSpacing (default 8dp), dotsColor, selectedDotColor, dotsCornerRadius (defaults to half of dotsSize), and dotsElevation. The SpringDotsIndicator adds dampingRatio (default 0.5) and stiffness (default 300) to control the spring physics parameters. The dotsClickable attribute, available on all XML types, enables navigating to a page by tapping its dot; it defaults to true.
Limitations and When to Look Elsewhere
The library does not support indicators for RecyclerView without a pager wrapper, since it connects specifically to ViewPager, ViewPager2, or Compose PagerState. There is no built-in vertical orientation option documented in the README.
Custom drawing beyond the provided types (for instance, a custom SVG shape for each dot) is not covered by the public API in the README; developers who need fully custom shapes must extend the library or draw their own component. The BalloonIndicatorType requires a dotSpacing parameter to avoid overlap at larger balloonSizeFactor values, as the README demonstrates with dotSpacing = 20.dp; getting this right may require manual tuning per design.
The README does not document the full history of breaking changes between major versions.
For teams using the XML view API, the WormDotsIndicator has its own set of XML attributes including dotsColor, dotsStrokeColor, dotsCornerRadius, dotsStrokeWidth, dotsSize, dotsSpacing, and dotsClickable. These mirror the Spring variant but do not include dampingRatio or stiffness, since the worm animation uses a different motion model. Each indicator type in XML requires its own class name in the layout file; there is no single unified view that switches type via an attribute.
Comparison with CircleIndicator
CircleIndicator (me.relex.circleindicator) is another Android pager indicator library. It provides a simpler API focused on a basic circle indicator with color transitions between active and inactive states, and supports ViewPager2 and RecyclerView. It does not include spring physics, worm stretch, or balloon scaling animations.
Dots Indicator offers more animation variety within the same library and adds Compose support in the same artifact. The trade-off is a slightly larger API surface: DotGraphic parameters and two separate APIs (Compose and XML) compared to CircleIndicator's more uniform configuration. Teams that need Compose support or a specific named animation style should use Dots Indicator. Teams targeting only XML layouts with a minimal circle indicator may find CircleIndicator simpler to configure.
Editorial conclusion
Dots Indicator is the right choice for Android teams that need a drop-in pager dot indicator with a visible animation style and support for both Jetpack Compose and legacy XML views in the same dependency. The four built-in types cover the most common animation patterns, and the library was last pushed on 2026-08-31. Teams that need a minimal footprint with no animation beyond a simple color change can use CircleIndicator, which has a smaller API surface. Before adopting this library, confirm that the dampingRatio and stiffness defaults in SpringIndicatorType match your motion design guidelines, since those values are documented but the README does not explain how to derive design-system-consistent values from a spec.
Frequently asked questions
How do I attach a DotsIndicator to a ViewPager2 in Kotlin?
Call dotsIndicator.attachTo(viewPager2) after setting the adapter on the ViewPager2. The same method accepts both ViewPager and ViewPager2, so the call is identical for both. Declare the indicator view in XML with the com.tbuonomo.viewpagerdotsindicator.DotsIndicator class name.
Which animation type should I choose for an onboarding screen?
The README does not recommend a specific type for onboarding. ShiftIndicatorType is the simplest setup with one DotGraphic parameter. SpringIndicatorType adds physics-based motion with configurable dampingRatio and stiffness. WormIndicatorType stretches the indicator between positions. Choose based on your motion design guidelines and the visual weight of the animation you want.
Does Dots Indicator work with Jetpack Compose Pager?
Yes. The DotsIndicator composable accepts a PagerState from androidx.compose.foundation.pager directly. Pass the PagerState and the total page count, and choose one of ShiftIndicatorType, SpringIndicatorType, WormIndicatorType, or BalloonIndicatorType as the type parameter.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tommybuonomo-dotsindicator)