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.
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()
}
}