dotsindicator
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.
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.
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, #143, #139, #135, #133, #131, #126, #109, #95, #93, #86, #85, #80, #78, #73, #68, #58
- Methods
setViewPagerandsetViewPager2are now deprecated and replaced byattachTo(...)
4.2
Fix #115
The library is now on MavenCentral.
The library name moves from com.tbuonomo.andrui:viewpagerdotsindicator to com.tbuonomo:dotsindicator
4.1.2
4.1.1
Fix crash
4.1
4.0
- Support of ViewPager2 (fix #40)
- Convert all the project to Kotlin
- Migration to AndroidX
- Fix #37: findViewById, causing missing adapter error
3.0.3
- Fix #20: Dots indicator initialises with the wrong number of dots initially
3.0.2
- Add attribute
selectedDotColorandprogressModetoDotsIndicator - Fix RTL issues and improve
DotsIndicatorglobally
2.1.0
- Add attribute
dotsStrokeColortoSpringDotsIndicatorandWormDotsIndicator
License
Copyright 2016 Tommy Buonomo
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

