Dotsindicator
Dots indicators for Android ViewPager and Compose
Install / Use
npx skills add tommybuonomo/dotsindicatorInstalls into whichever agent you are using.
README
Pager Dots Indicator
<a href="https://github.com/JStumpp/awesome-android"><img alt="awesome" src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" /></a>
Dots Indicator is an Android library for Jetpack Compose and classic XML views 🚀
Compose support is built into the same artifact and exposes four indicator types: Shift, Spring, Worm, and Balloon.
<img src="https://github.com/tommybuonomo/dotsindicator/assets/15737675/77651550-3819-4fbf-8528-0d28c95d4d07" height="500"/>Don't forget to star the project if you like it!
== 
Feel free to submit issues and enhancement requests!
Installation
Add Maven Central and the library dependency:
repositories {
google()
mavenCentral()
}
dependencies {
implementation("com.tbuonomo:dotsindicator:5.1.1")
}
Jetpack Compose
DotsIndicator works directly with androidx.compose.foundation.pager.PagerState.
ShiftIndicatorType
DotsIndicator(
dotCount = pageCount,
type = ShiftIndicatorType(
dotsGraphic = DotGraphic(color = MaterialTheme.colorScheme.primary)
),
pagerState = pagerState
)
SpringIndicatorType
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
DotsIndicator(
dotCount = pageCount,
type = WormIndicatorType(
dotsGraphic = DotGraphic(
size = 16.dp,
borderWidth = 2.dp,
borderColor = MaterialTheme.colorScheme.primary,
color = Color.Transparent,
),
wormDotGraphic = DotGraphic(
size = 16.dp,
color = MaterialTheme.colorScheme.primary,
)
),
pagerState = pagerState
)
BalloonIndicatorType
DotsIndicator(
dotCount = pageCount,
type = BalloonIndicatorType(
dotsGraphic = DotGraphic(
size = 8.dp,
color = MaterialTheme.colorScheme.primary
),
balloonSizeFactor = 2f
),
dotSpacing = 20.dp,
pagerState = pagerState
)
XML views
Classic Android views are still supported for ViewPager and ViewPager2 with attachTo(...).
DotsIndicator

XML layout
<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:dotsCornerRadius="8dp"
app:dotsElevation="4dp"
app:dotsSize="16dp"
app:dotsSpacing="4dp"
app:dotsWidthFactor="2.5"
app:selectedDotColor="@color/md_blue_200"
app:progressMode="true"
app:dotsClickable="true" />
Custom attributes
| Attribute | Description |
| --- | --- |
| dotsColor | Color of the dots |
| selectedDotColor | Color of the selected dot (defaults to dotsColor) |
| progressMode | Colors every previous dot with the selected dot color |
| dotsSize | Size of the dots (default: 16dp) |
| dotsSpacing | Space between dots (default: 8dp) |
| dotsWidthFactor | Width multiplier for the selected dot (default: 2.5) |
| dotsCornerRadius | Dot corner radius (defaults to half of dotsSize) |
| dotsElevation | Elevation applied to the dots |
| dotsClickable | Enables changing page when a dot is tapped (default: true) |
Kotlin
val dotsIndicator = findViewById<DotsIndicator>(R.id.dots_indicator)
val viewPager = findViewById<ViewPager2>(R.id.view_pager)
viewPager.adapter = ViewPagerAdapter()
dotsIndicator.attachTo(viewPager)
SpringDotsIndicator

XML layout
<com.tbuonomo.viewpagerdotsindicator.SpringDotsIndicator
android:id="@+id/spring_dots_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:dampingRatio="0.5"
app:dotsColor="@color/material_white"
app:dotsStrokeColor="@color/material_yellow"
app:dotsCornerRadius="2dp"
app:dotsSize="16dp"
app:dotsSpacing="6dp"
app:dotsStrokeWidth="2dp"
app:stiffness="300"
app:dotsClickable="true" />
Custom attributes
| Attribute | Description |
| --- | --- |
| dotsColor | Color of the moving indicator dot |
| dotsStrokeColor | Color of the stroke dots (defaults to the indicator color) |
| dotsSize | Size of the dots (default: 16dp) |
| dotsSpacing | Space between dots (default: 4dp) |
| dotsCornerRadius | Dot corner radius (defaults to half of dotsSize) |
| dotsStrokeWidth | Stroke width for the background dots (default: 2dp) |
| dampingRatio | Spring force damping ratio (default: 0.5) |
| stiffness | Spring force stiffness (default: 300) |
| dotsClickable | Enables changing page when a dot is tapped (default: true) |
Kotlin
val springDotsIndicator = findViewById<SpringDotsIndicator>(R.id.spring_dots_indicator)
val viewPager = findViewById<ViewPager2>(R.id.view_pager)
viewPager.adapter = ViewPagerAdapter()
springDotsIndicator.attachTo(viewPager)
WormDotsIndicator

XML layout
<com.tbuonomo.viewpagerdotsindicator.WormDotsIndicator
android:id="@+id/worm_dots_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:dotsColor="@color/material_blueA200"
app:dotsStrokeColor="@color/material_yellow"
app:dotsCornerRadius="8dp"
app:dotsSize="16dp"
app:dotsSpacing="4dp"
app:dotsStrokeWidth="2dp"
app:dotsClickable="true" />
Custom attributes
| Attribute | Description |
| --- | --- |
| dotsColor | Color of the moving indicator dot |
| dotsStrokeColor | Color of the stroke dots (defaults to the indicator color) |
| dotsSize | Size of the dots (default: 16dp) |
| dotsSpacing | Space between dots (default: 4dp) |
| dotsCornerRadius | Dot corner radius (defaults to half of dotsSize) |
| dotsStrokeWidth | Stroke width for the background dots (default: 2dp) |
| dotsClickable | Enables changing page when a dot is tapped (default: true) |
Kotlin
val wormDotsIndicator = findViewById<WormDotsIndicator>(R.id.worm_dots_indicator)
val viewPager = findViewById<ViewPager2>(R.id.view_pager)
viewPager.adapter = ViewPagerAdapter()
wormDotsIndicator.attachTo(viewPager)
ViewPager and ViewPager2
attachTo(...) accepts both androidx.viewpager.widget.ViewPager and androidx.viewpager2.widget.ViewPager2:
dotsIndicator.attachTo(viewPager)
dotsIndicator.attachTo(viewPager2)
Help Maintenance
If you could help me to continue maintain this repo, buying me a cup of coffee will make my life really happy and get much energy out of it.
<a href="https://www.buymeacoffee.com/tommybuonomo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/purple_img.png" alt="Buy Me A Coffee" style="height: auto !important;width: auto !important;" ></a>
Changelog
5.1.1
- Fix RTL crashes and direction issues across classic and Compose indicators, including Worm and Spring behavior in RTL layouts
- Fix indicator state regressions: RTL rotation now resets correctly when returning to LTR, and fast-scroll dot colors no longer get stuck out of sync
- Add Compose regression coverage for Shift, Balloon, Spring, and Worm indicators with computation, behavior, and screenshot tests in both LTR and RTL
- Fix #207, #209, and #211
5.1.0
- Fix import issues
- Upgrade AGP versions
- Migrate repo to Maven Central Repository
5.0
- Add Jetpack Compose support with 4 types: ShiftIndicatorType, SpringIndicatorType, WormIndicatorType, BalloonIndicatorType
4.3
- Fix [#144][i144], [#14
Related Skills
obsidian
385.5kWork with Obsidian vaults using the official obsidian CLI: read/search/create/edit notes, tasks, links, properties, plugins.
html-anything
8.1k✨ The agentic HTML editor — your local AI agent writes the HTML, you ship it. 🚀 75 Skills × 9 Surfaces (magazine · deck · poster · XHS / tweet · prototype · data report · Hyperframes) 🛡️ Sandboxed preview · 📤 1-click to WeChat / X / Zhihu / HTML / PNG 🔑 Zero API key — Claude Code / Cursor / Code…
openpencil
4.7kThe world's first open-source AI-native vector design tool and the first to feature concurrent Agent Teams. Design-as-Code. Turn prompts into UI directly on the live canvas. A modern alternative to Pencil.
openpencil
4.7kThe world's first open-source AI-native vector design tool and the first to feature concurrent Agent Teams. Design-as-Code. Turn prompts into UI directly on the live canvas. A modern alternative to Pencil.
