ProgressArcView implementation for Android
Would you like the same progress View?
Here is source code for simple viewsion without customisation from XML.
package com.hrupin.samples.roundanimation; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.os.Bundle; import android.os.Parcelable; import android.util.AttributeSet; import android.view.View; /** * Created by Igor Khrupin www.hrupin.com on 03-05-2017. */ public class ProgressArcView extends View { private Paint finishedPaint; private Paint unfinishedPaint; private Paint innerCirclePaint; private RectF finishedOuterRect = new RectF(); private RectF unfinishedOuterRect = new RectF(); private float progress = 0; private int max = 1000; private int finishedStrokeColor = Color.parseColor("#ff0000"); private int unfinishedStrokeColor = Color.parseColor("#4cff0000"); private int startingDegree = -90; private float strokeWidth = dp2px(getResources(), 14.5f); private int innerBackgroundColor = Color.parseColor("#ffffff"); private int minSize = (int) dp2px(getResources(), 270); private static final String INSTANCE_STATE = "saved_instance"; private static final String INSTANCE_MAX = "max"; private static final String INSTANCE_PROGRESS = "progress"; private static final String INSTANCE_STARTING_DEGREE = "starting_degree"; public ProgressArcView(Context context) { this(context, null); } public ProgressArcView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ProgressArcView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initPainters(); } protected void initPainters() { finishedPaint = new Paint(); finishedPaint.setAntiAlias(true); finishedPaint.setColor(finishedStrokeColor); finishedPaint.setStyle(Paint.Style.STROKE); finishedPaint.setStrokeWidth(strokeWidth); unfinishedPaint = new Paint(); unfinishedPaint.setAntiAlias(true); unfinishedPaint.setColor(unfinishedStrokeColor); unfinishedPaint.setStyle(Paint.Style.STROKE); unfinishedPaint.setStrokeWidth(strokeWidth); innerCirclePaint = new Paint(); innerCirclePaint.setAntiAlias(true); innerCirclePaint.setColor(innerBackgroundColor); } @Override public void invalidate() { initPainters(); super.invalidate(); } private float getProgressAngle() { return getProgress() / (float) max * 360f; } public float getProgress() { return progress; } public void setProgress(float progress) { this.progress = progress; if (this.progress > getMax()) { this.progress %= getMax(); } invalidate(); } public int getMax() { return max; } public void setMax(int max) { if (max > 0) { this.max = max; invalidate(); } } public int getStartingDegree() { return startingDegree; } public void setStartingDegree(int startingDegree) { this.startingDegree = startingDegree; this.invalidate(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec)); } private int measure(int measureSpec) { int result; int mode = MeasureSpec.getMode(measureSpec); int size = MeasureSpec.getSize(measureSpec); if (mode == MeasureSpec.EXACTLY) { result = size; } else { result = minSize; if (mode == MeasureSpec.AT_MOST) { result = Math.min(result, size); } } return result; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float delta = strokeWidth / 2f; finishedOuterRect.set(delta, delta, getWidth() - delta, getHeight() - delta); unfinishedOuterRect.set(delta, delta, getWidth() - delta, getHeight() - delta); float innerCircleRadius = getWidth() / 2f - strokeWidth; canvas.drawArc(unfinishedOuterRect, getStartingDegree() + getProgressAngle(), 360 - getProgressAngle(), false, unfinishedPaint); canvas.drawArc(finishedOuterRect, getStartingDegree(), getProgressAngle(), false, finishedPaint); canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, innerCircleRadius, innerCirclePaint); } @Override protected Parcelable onSaveInstanceState() { final Bundle bundle = new Bundle(); bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState()); bundle.putInt(INSTANCE_MAX, getMax()); bundle.putInt(INSTANCE_STARTING_DEGREE, getStartingDegree()); bundle.putFloat(INSTANCE_PROGRESS, getProgress()); return bundle; } @Override protected void onRestoreInstanceState(Parcelable state) { if (state instanceof Bundle) { final Bundle bundle = (Bundle) state; initPainters(); setMax(bundle.getInt(INSTANCE_MAX)); setStartingDegree(bundle.getInt(INSTANCE_STARTING_DEGREE)); setProgress(bundle.getFloat(INSTANCE_PROGRESS)); super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE)); return; } super.onRestoreInstanceState(state); } public static float dp2px(Resources resources, float dp) { final float scale = resources.getDisplayMetrics().density; return dp * scale + 0.5f; } }
And here is ProgressArcView usage.
I’ve implemented delay for click action using this view.
Case:
Click action will activated it user hold round button during 10 seconds.
package com.hrupin.samples.roundanimation; import android.animation.Animator; import android.animation.ValueAnimator; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.animation.LinearInterpolator; public class MainActivity extends AppCompatActivity implements View.OnTouchListener { private ProgressArcView progressArcView; private ValueAnimator progressAnim; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progressArcView = (ProgressArcView)findViewById(R.id.progressArcView); progressArcView.setProgress(0); progressArcView.setOnTouchListener(this); } @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN){ startProgress(); }else if(event.getAction() == MotionEvent.ACTION_UP){ if(progressAnim != null){ progressAnim.end(); } progressAnim = null; if(progressArcView != null){ progressArcView.setProgress(0); } } return true; } private void startProgress() { if(progressAnim == null) { progressAnim = ValueAnimator.ofInt(0, progressArcView.getMax()); progressAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { Integer value = (Integer) animation.getAnimatedValue(); if(progressArcView != null){ progressArcView.setProgress(value); } } }); progressAnim.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { if(progressArcView != null){ progressArcView.setProgress(0); } progressAnim = null; } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); progressAnim.setDuration(10000); progressAnim.setInterpolator(new LinearInterpolator()); progressAnim.start(); } } }
Source code:
0 Comments