CircularSeekBar
???? CircularSeekBar is a circular progress bar/seek bar android library that supports animations, dashes and gradients.
Getting Started
Youtube Demo Video
An example project can be found in the example directory of this repository.
Basic Examples
1. Basic SeekBar
Xml code:
If you want to use thumb, set the thumb property values.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.seosh817.circularseekbar.CircularSeekBar
android:id="@+id/circular_seek_bar"
android:layout_width="match_parent"
android:layout_height="300dp"
app:circularSeekBar_animation="normal"
app:circularSeekBar_animationDurationMillis="1000"
app:circularSeekBar_barWidth="8dp"
app:circularSeekBar_innerThumbRadius="5dp"
app:circularSeekBar_innerThumbStrokeWidth="3dp"
app:circularSeekBar_min="0"
app:circularSeekBar_outerThumbRadius="5dp"
app:circularSeekBar_outerThumbStrokeWidth="10dp"
app:circularSeekBar_startAngle="90"
app:circularSeekBar_sweepAngle="360"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
2. Gradient SeekBar
Xml code(colors.xml):
<resources>
<color name="red">#FFF44336</color>
<color name="orange">#FFFFAB40</color>
<color name="yellow">#FFFFEB3B</color>
<color name="green">#FF4CAF50</color>
<color name="blue">#FF2196F3</color>
<color name="indigo">#FF3F51B5</color>
<color name="purple">#FF9C27B0</color>
<array name="rainbow">
<item>@color/red</item>
<item>@color/orange</item>
<item>@color/yellow</item>
<item>@color/green</item>
<item>@color/blue</item>
<item>@color/indigo</item>
<item>@color/purple</item>
</array>
</resources>
Xml code(activity_main.xml):
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.seosh817.circularseekbar.CircularSeekBar
android:id="@+id/circular_seek_bar"
android:layout_width="match_parent"
android:layout_height="300dp"
app:circularSeekBar_animation="normal"
app:circularSeekBar_animationDurationMillis="1000"
app:circularSeekBar_barWidth="8dp"
app:circularSeekBar_innerThumbRadius="5dp"
app:circularSeekBar_innerThumbStrokeWidth="3dp"
app:circularSeekBar_min="0"
app:circularSeekBar_outerThumbRadius="5dp"
app:circularSeekBar_outerThumbStrokeWidth="10dp"
app:circularSeekBar_startAngle="45"
app:circularSeekBar_sweepAngle="270"
app:circularSeekBar_progressGradientColors="@array/rainbow"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
3. Dashed SeekBar
Xml code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.seosh817.circularseekbar.CircularSeekBar
android:id="@+id/circular_seek_bar"
android:layout_width="match_parent"
android:layout_height="300dp"
app:circularSeekBar_animation="normal"
app:circularSeekBar_animationDurationMillis="1000"
app:circularSeekBar_barWidth="8dp"
app:circularSeekBar_dashGap="15"
app:circularSeekBar_dashWidth="50"
app:circularSeekBar_innerThumbRadius="5dp"
app:circularSeekBar_innerThumbStrokeWidth="3dp"
app:circularSeekBar_min="0"
app:circularSeekBar_outerThumbRadius="5dp"
app:circularSeekBar_outerThumbStrokeWidth="10dp"
app:circularSeekBar_progressGradientColors="@array/rainbow"
app:circularSeekBar_startAngle="90"
app:circularSeekBar_sweepAngle="180"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Xml code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.seosh817.circularseekbar.CircularSeekBar
android:id="@+id/circular_seek_bar"
android:layout_width="match_parent"
android:layout_height="300dp"
app:circularSeekBar_animation="normal"
app:circularSeekBar_animationDurationMillis="1000"
app:circularSeekBar_barWidth="8dp"
app:circularSeekBar_innerThumbRadius="5dp"
app:circularSeekBar_innerThumbStrokeWidth="3dp"
app:circularSeekBar_min="0"
app:circularSeekBar_outerThumbRadius="5dp"
app:circularSeekBar_outerThumbStrokeWidth="10dp"
app:circularSeekBar_progressGradientColors="@array/rainbow"
app:circularSeekBar_startAngle="45"
app:circularSeekBar_dashWidth="80"
app:circularSeekBar_dashGap="15"
app:circularSeekBar_sweepAngle="270"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Xml code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.seosh817.circularseekbar.CircularSeekBar
android:id="@+id/circular_seek_bar"
android:layout_width="match_parent"
android:layout_height="300dp"
app:circularSeekBar_animation="normal"
app:circularSeekBar_animationDurationMillis="1000"
app:circularSeekBar_barStrokeCap="butt"
app:circularSeekBar_barWidth="8dp"
app:circularSeekBar_innerThumbRadius="5dp"
app:circularSeekBar_innerThumbStrokeWidth="3dp"
app:circularSeekBar_min="0"
app:circularSeekBar_outerThumbRadius="5dp"
app:circularSeekBar_outerThumbStrokeWidth="10dp"
app:circularSeekBar_progressGradientColors="@array/rainbow"
app:circularSeekBar_startAngle="45"
app:circularSeekBar_dashWidth="1"
app:circularSeekBar_dashGap="2"
app:circularSeekBar_sweepAngle="270"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
4. Listen to the progress changed.
Xml code:
If you want to listen for value changes, implement the interface setOnProgressChangedListener
or setOnAnimationEndListener
.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
with(binding) {
circularSeekBar.setOnProgressChangedListener { progress ->
tvProgressValue.text = progress
.roundToInt()
.toString()
}
circularSeekBar.setOnAnimationEndListener { _ ->
// listen
}
}
}
}
5. Animations
Xml code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.seosh817.circularseekbar.CircularSeekBar
android:id="@+id/circular_seek_bar"
android:layout_width="match_parent"
android:layout_height="300dp"
app:circularSeekBar_animation="bounce"
app:circularSeekBar_animationDurationMillis="1000"
app:circularSeekBar_barStrokeCap="butt"
app:circularSeekBar_barWidth="8dp"
app:circularSeekBar_innerThumbRadius="5dp"
app:circularSeekBar_innerThumbStrokeWidth="3dp"
app:circularSeekBar_min="0"
app:circularSeekBar_outerThumbRadius="5dp"
app:circularSeekBar_outerThumbStrokeWidth="10dp"
app:circularSeekBar_progressGradientColors="@array/rainbow"
app:circularSeekBar_startAngle="45"
app:circularSeekBar_dashWidth="1"
app:circularSeekBar_dashGap="2"
app:circularSeekBar_sweepAngle="270"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Kotlin code:
If you want to change the SeekBar's animation, implement the CircularSeekBar Animation properties.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
with(binding) {
circularSeekBar.circularSeekBarAnimation = CircularSeekBarAnimation.BOUNCE // NORMAL, BOUNCE, DECELERATE, ACCELERATE_DECELERATE
circularSeekBar.animationDurationMillis = 1000
}
}
}
If you want to apply a custom animation, implement the animationInterpolator property.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
with(binding) {
circularSeekBar.animationInterpolator = AccelerateInterpolator()
circularSeekBar.animationDurationMillis = 1000
}
}
}
Installing
Gradle
Add mavenCentral()
to your project build.gradle file.
allprojects {
repositories {
mavenCentral()
}
}
Then, add dependency to your module's build.gradle file.
dependencies {
implementation "com.seosh817:circularseekbar:1.0.2"
}
Properties
You can customize the CircularSeekBar using the following properties:
Property | Type | Default | Description |
---|---|---|---|
progress | Float | 0f | Current value of seek bar. |
min | Float | 0f | Minimum value of seek bar. |
max | Float | 100f | Maximum value of seek bar. |
startAngle | Float | 0f | The Angle to start drawing this seek bar from. |
sweepAngle | Float | 360f | The Angle through which to draw the seek bar. |
barWidth | Float | 6f | The thickness of the seek bar. |
trackColor | Color | Color.LTGRAY | Background track color of seek bar. |
trackGradientColors | IntArray | intArrayOf() | Background track gradient colors of seek bar. If [trackGradientColors] is not empty, [trackColor] is not applied. |
progressColor | Color | Color.parseColor("#FF189BFA") | Foreground progress color of seek bar. |
progressGradientColors | IntArray | intArrayOf() | Foreground progressGradientColors of seek bar. If [progressGradientColors] is not empty, [progressColor] is not applied. |
strokeCap | BarStrokeCap | BarStrokeCap.ROUND | Styles to use for arcs endings. |
showAnimation | Boolean | true | Active seek bar animation. |
circularSeekBarAnimation | CircularSeekBarAnimation | CircularSeekBarAnimation.BOUNCE | Animation of [CircularSeekBar]. |
animDurationMillis | Int | 1000 | Animation duration milliseconds. |
innerThumbRadius | Float | 0f | The radius of the [CircularSeekBar] inner thumb. |
innerThumbStrokeWidth | Float | 0f | The stroke width of the [CircularSeekBar] inner thumb. |
innerThumbColor | Color | Color.parseColor("#FF189BFA") | Color of the [CircularSeekBar] inner thumb. |
innerThumbStyle | ThumbStyle | ThumbStyle.FILL_AND_STROKE | Style of the [CircularSeekBar] inner thumb. |
outerThumbRadius | Float | 0f | The radius of the [CircularSeekBar] outer thumb. |
outerThumbStrokeWidth | Float | 0f | The stroke width of the [CircularSeekBar] outer thumb. |
outerThumbColor | Color | Color.WHITE | Color of the [CircularSeekBar] outer thumb. |
outerThumbStyle | ThumbStyle | ThumbStyle.FILL_AND_STROKE | Style of the [CircularSeekBar] outer thumb. |
dashWidth | Float | 0f | Dash width of [CircularSeekBar]. |
dashGap | Float | 0f | Dash gap of [CircularSeekBar]. |
interactive | Boolean | true | Set to true if you want to interact with TapDown to change the seekbar's progress. |
License
Copyright 2023 seosh817 (Seunghwan Seo)
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.
Contribution
Feel free to file an issue if you find a problem or make pull requests.
All contributions are welcome ????