Android circular progress bar with rounded corners
Asked Answered
H

4

29

I am trying to get a circular progress bar with rounded corner as shown below. enter image description here

But I am not able to get the rounded corner so far I am able to get the circular progress bar. enter image description here

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.

Harvard answered 15/4, 2016 at 6:24 Comment(10)
add corner to in @android:id/progressAinu
@Pravin I tried it already but it didn't work. It seems corner is only for rectangle shape.Harvard
Try this library for the same :Progress WidgetNovelist
@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.Harvard
Check out this answer #31219955Sato
u should go for custom progress barGlosseme
Did you find any solution?Nudism
@M.RezaNasirloo I have posted an answer which might be helpful to you.Bulley
@VipulAsri did you find any solution?Kobylak
If 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. ( :Melloney
T
15

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()
  }
}
Torquay answered 18/12, 2018 at 9:52 Comment(3)
Thank you for great solution! One clarification question: In updateRect method, to get the circles drawn edge to edge, isn't it better to divide obtained strokeWidth by 2 before setting rect coordinates? With current setup there are small paddings around the rectangle.Titanesque
What language is this written in?Dodgem
above program written in KotlinEtheridge
Q
12

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" />
Quadrinomial answered 29/4, 2021 at 6:17 Comment(0)
B
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

Bulley answered 31/3, 2018 at 18:2 Comment(0)
B
1

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.

Image from my apk

Blastocyst answered 14/12, 2020 at 22:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.