Android circular progress bar with rounded corners
Solution 1
A simple and efficient class extending View
to draw circular progress, with rounded corners as an option. Progress color, background color, stroke width are also customizable.
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import androidx.annotation.FloatRange
class CircularProgressView : View {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
private val progressPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
style = Paint.Style.STROKE
}
private val backgroundPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
style = Paint.Style.STROKE
}
private val rect = RectF()
private val startAngle = -90f
private val maxAngle = 360f
private val maxProgress = 100
private var diameter = 0f
private var angle = 0f
override fun onDraw(canvas: Canvas) {
drawCircle(maxAngle, canvas, backgroundPaint)
drawCircle(angle, canvas, progressPaint)
}
override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) {
diameter = Math.min(width, height).toFloat()
updateRect()
}
private fun updateRect() {
val strokeWidth = backgroundPaint.strokeWidth
rect.set(strokeWidth, strokeWidth, diameter - strokeWidth, diameter - strokeWidth)
}
private fun drawCircle(angle: Float, canvas: Canvas, paint: Paint) {
canvas.drawArc(rect, startAngle, angle, false, paint)
}
private fun calculateAngle(progress: Float) = maxAngle / maxProgress * progress
fun setProgress(@FloatRange(from = 0.0, to = 100.0) progress: Float) {
angle = calculateAngle(progress)
invalidate()
}
fun setProgressColor(color: Int) {
progressPaint.color = color
invalidate()
}
fun setProgressBackgroundColor(color: Int) {
backgroundPaint.color = color
invalidate()
}
fun setProgressWidth(width: Float) {
progressPaint.strokeWidth = width
backgroundPaint.strokeWidth = width
updateRect()
invalidate()
}
fun setRounded(rounded: Boolean) {
progressPaint.strokeCap = if (rounded) Paint.Cap.ROUND else Paint.Cap.BUTT
invalidate()
}
}
Solution 2
Use the Material CircularProgressIndicator
and use app:trackCornerRadius="5dp"
to get the curved progress indicator.
<com.google.android.material.progressindicator.CircularProgressIndicator
app:indicatorSize="95dp"
android:progress="60"
app:trackCornerRadius="5dp"
app:trackThickness="6dp"
app:trackColor="@color/track_color"
app:indicatorColor="@color/yellow_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Solution 3
I know this is an old question. But here is a solution which might be helpful to someone else.
This library can be used to achieve this.
Simply add this to your Gradel File
compile 'pl.pawelkleczkowski.customgauge:CustomGauge:1.0.3'
And then add this to you XML Layout
<pl.pawelkleczkowski.customgauge.CustomGauge
android:id="@+id/gauge2"
android:layout_width="140dp"
android:layout_height="140dp"
android:layout_centerHorizontal="true"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
app:gaugeEndValue="100"
app:gaugePointEndColor="@color/md_blue_800"
app:gaugePointStartColor="@color/md_blue_300"
app:gaugeStartAngle="180"
app:gaugeStartValue="0"
app:gaugeStrokeCap="ROUND"
app:gaugeStrokeColor="@color/md_grey_400"
app:gaugeStrokeWidth="10dp"
app:gaugeSweepAngle="360" />
And this is how you can set the progress of the bar
private CustomGauge gauge;// Declare this variable in your activity
gauge = findViewById(R.id.gauge2);//And this on you OnCreate method
gauge.setValue(progress);// Set the progress like this.
The library is Opensource and is available to use under the General Public License, version 2
Solution 4
Library
compile 'pl.pawelkleczkowski.customgauge:CustomGauge:1.0.4'
XML CODE
<pl.pawelkleczkowski.customgauge.CustomGauge
android:id="@+id/progressbar"
android:layout_width="@dimen/dimens_550px"
android:layout_height="@dimen/dimens_550px"
app:layout_constraintStart_toStartOf="@id/lottie_empty"
app:layout_constraintEnd_toEndOf="@id/lottie_empty"
app:layout_constraintTop_toTopOf="@id/lottie_empty"
app:layout_constraintBottom_toBottomOf="@id/lottie_empty"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
app:gaugePointEndColor="#3DEBFF"
app:gaugePointStartColor="#246887"
app:gaugeStartAngle="270"
app:gaugeStrokeCap="ROUND"
app:gaugeStrokeColor="#80777777"
app:gaugeStrokeWidth="10dp"
app:gaugeSweepAngle="360"
/>
Code java
private CustomGauge gauge;// Declare this variable in your activity
gauge = findViewById(R.id.gauge2);//And this on you OnCreate method
gauge.setEndValue(max_progress);// Set the max progress like this.
gauge.setValue(progress);// Set the progress like this.
Related videos on Youtube
Rakesh
Hi, I'm Rakesh, a Staff Software Engineer with extensive experience in highly distributed & scalable systems Website: http://portfolio.rakeshkumar.info
Updated on April 29, 2021Comments
-
Rakesh about 3 years
I am trying to get a circular progress bar with rounded corner as shown below.
But I am not able to get the rounded corner so far I am able to get the circular progress bar.
I am trying to draw it using the xml drawable.
<ProgressBar android:id="@+id/onboarding_activity_progress_bar" android:layout_gravity="center" android:padding="10dp" android:layout_width="120dp" android:layout_height="120dp" style="?android:attr/progressBarStyleHorizontal" android:progressDrawable="@drawable/progressbar_onboarding_view" tools:progress="60"/>
Progressbar_onboarding_view.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape android:useLevel="false" android:innerRadiusRatio="2.0" android:shape="ring" android:thickness="10dp"> <solid android:color="@color/progress_bar_background_color" /> <corners android:radius="50dp"/> </shape> </item> <item android:id="@android:id/progress"> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:useLevel="true" android:innerRadiusRatio="2.0" android:shape="ring" android:thickness="10dp"> <solid android:color="@color/progress_bar_color" /> </shape> <!-- <scale android:drawable="@drawable/progressbar_round_corner" android:scaleWidth="98%" /> --> </item> </layer-list>
progressbar_rounded_corner.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <corners android:radius="10dp"/> <solid android:color="@android:color/white" /> <stroke android:width="1dp" android:color="@android:color/holo_red_dark" /> </shape>
I tried using scale parameter but the progress corner didn't change. I am not sure how to achieve the rounded corner. Please help I would really appreciate it.
-
Pavya about 8 yearsadd corner to in @android:id/progress
-
Rakesh about 8 years@Pravin I tried it already but it didn't work. It seems corner is only for rectangle shape.
-
Vipul Asri about 8 yearsTry this library for the same :Progress Widget
-
Rakesh about 8 years@VipulAsri thank you for the suggestion but I don't want to use a third party library. Because I want to be under dex limit and my app is already very close to dex limit.
-
satorikomeiji about 8 yearsCheck out this answer stackoverflow.com/questions/31219455/…
-
kukku over 6 yearsu should go for custom progress bar
-
M. Reza Nasirloo about 6 yearsDid you find any solution?
-
Rahulrr2602 about 6 years@M.RezaNasirloo I have posted an answer which might be helpful to you.
-
iamnaran over 5 years@VipulAsri did you find any solution?
-
Nate T about 3 yearsIf it were me, I'd use a GIF. Once in a while, the simplest solution and the best solution are one and the same... BTW if you use this solution, let me know so I can add an answer and get the rep. ( :
-
-
Marat about 4 yearsThank you for great solution! One clarification question: In
updateRect
method, to get the circles drawn edge to edge, isn't it better to divide obtainedstrokeWidth
by 2 before setting rect coordinates? With current setup there are small paddings around the rectangle. -
David Rector over 2 yearsWhat language is this written in?
-
Prateek over 2 yearsabove program written in Kotlin