I have a ProgressBar :

layout.xml

 <ProgressBar android:id="@+id/progressBar_result_learn" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="20dp" android:progressDrawable="@drawable/progregress_bar_drawable" android:rotation="270" /> 

proress_drawable.xml

 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape android:innerRadiusRatio="2.3" android:shape="ring" android:thickness="3.8sp"> <solid android:color="@color/colorBackgroundGrey" /> </shape> </item> <item android:id="@android:id/progress" > <clip> <shape android:innerRadiusRatio="2.3" android:shape="ring" android:thickness="3.8sp"> <solid android:color="@color/green" /> </shape> </clip> </item> </layer-list> 

During the animation of progress, progress fills it as if it is lazy, even if in a circle. and I want the filling to take place like a from 12 o'clock to 12 clockwise.

Here's how it turns out for me, progress is going both to the left and to the right, how to make it so that it goes in the direction I need

enter image description here

1 answer 1

Here is a simple solution.

CircleProgressBar.java

 public class CircleProgressBar extends View { /** * ProgressBar's line thickness */ private float strokeWidth = 4; private float progress = 0; private int min = 0; private int max = 100; /** * Start the progress at 12 o'clock */ private int startAngle = -90; private int color = Color.DKGRAY; private RectF rectF; private Paint backgroundPaint; private Paint foregroundPaint; /**Animation duration */ private int animDuration = 5000; public float getStrokeWidth() { return strokeWidth; } public void setStrokeWidth(float strokeWidth) { this.strokeWidth = strokeWidth; backgroundPaint.setStrokeWidth(strokeWidth); foregroundPaint.setStrokeWidth(strokeWidth); invalidate(); requestLayout();//Because it should recalculate its bounds } public float getProgress() { return progress; } public void setProgress(float progress) { this.progress = progress; invalidate(); } public int getMin() { return min; } public void setMin(int min) { this.min = min; invalidate(); } public int getMax() { return max; } public void setMax(int max) { this.max = max; invalidate(); } public int getColor() { return color; } public void setColor(int color) { this.color = color; backgroundPaint.setColor(adjustAlpha(color, 0.3f)); foregroundPaint.setColor(color); invalidate(); requestLayout(); } public int getAnimDuration() { return animDuration; } public void setAnimDuration(int animDuration) { this.animDuration = animDuration; } public CircleProgressBar(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } private void init(Context context, AttributeSet attrs) { rectF = new RectF(); TypedArray typedArray = context.getTheme().obtainStyledAttributes( attrs, R.styleable.CircleProgressBar, 0, 0); //Reading values from the XML layout try { strokeWidth = typedArray.getDimension(R.styleable.CircleProgressBar_progressBarThickness, strokeWidth); progress = typedArray.getFloat(R.styleable.CircleProgressBar_my_circle_progress, progress); color = typedArray.getInt(R.styleable.CircleProgressBar_progressbarColor, color); min = typedArray.getInt(R.styleable.CircleProgressBar_min, min); max = typedArray.getInt(R.styleable.CircleProgressBar_max, max); } finally { typedArray.recycle(); } backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); backgroundPaint.setColor(adjustAlpha(color, 0.3f)); backgroundPaint.setStyle(Paint.Style.STROKE); backgroundPaint.setStrokeWidth(strokeWidth); foregroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); foregroundPaint.setColor(color); foregroundPaint.setStyle(Paint.Style.STROKE); foregroundPaint.setStrokeWidth(strokeWidth); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawOval(rectF, backgroundPaint); float angle = 360 * progress / max; canvas.drawArc(rectF, startAngle, angle, false, foregroundPaint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); final int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec); final int min = Math.min(width, height); setMeasuredDimension(min, min); rectF.set(0 + strokeWidth / 2, 0 + strokeWidth / 2, min - strokeWidth / 2, min - strokeWidth / 2); } /** * Lighten the given color by the factor * * @param color The color to lighten * @param factor 0 to 4 * @return A brighter color */ public int lightenColor(int color, float factor) { float r = Color.red(color) * factor; float g = Color.green(color) * factor; float b = Color.blue(color) * factor; int ir = Math.min(255, (int) r); int ig = Math.min(255, (int) g); int ib = Math.min(255, (int) b); int ia = Color.alpha(color); return (Color.argb(ia, ir, ig, ib)); } /** * Transparent the given color by the factor * The more the factor closer to zero the more the color gets transparent * * @param color The color to transparent * @param factor 1.0f to 0.0f * @return int - A transplanted color */ public int adjustAlpha(int color, float factor) { int alpha = Math.round(Color.alpha(color) * factor); int red = Color.red(color); int green = Color.green(color); int blue = Color.blue(color); return Color.argb(alpha, red, green, blue); } /** * Set the progress with an animation. * Note that the {@link android.animation.ObjectAnimator} Class automatically set the progress * so don't call the {@link CircleProgressBar#setProgress(float)} directly within this method. * * @param progress The progress it should animate to it. */ public void setProgressWithAnimation(float progress) { ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(this, "progress", progress); objectAnimator.setDuration(animDuration); objectAnimator.setInterpolator(new DecelerateInterpolator(0.8f)); objectAnimator.start(); } 

res / values ​​/ attrs.xml

 <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CircleProgressBar"> <attr name="min" format="integer" /> <attr name="max" format="integer" /> <attr name="my_circle_progress" format="integer" /> <attr name="progressbarColor" format="color" /> <attr name="progressBarThickness" format="dimension" /> </declare-styleable> </resources> 

Taken from here