package com.loopeer.codereader.ui.view;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;
import com.loopeer.codereader.R;
import java.util.ArrayList;
import java.util.List;
public class ProgressIndicatorView extends View {
float scaleFloat1, scaleFloat2, degrees;
public static final int DEFAULT_SIZE = 45;
int mIndicatorColor;
Paint mPaint;
private List<Animator> mAnimators;
private boolean mHasAnimation;
public ProgressIndicatorView(Context context) {
this(context, null);
}
public ProgressIndicatorView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ProgressIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
mIndicatorColor = ContextCompat.getColor(getContext(), R.color.colorPrimary);
mPaint = new Paint();
mPaint.setColor(mIndicatorColor);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
setAnimationStatus(AnimStatus.START);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
setAnimationStatus(AnimStatus.CANCEL);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = measureDimension(dp2px(DEFAULT_SIZE), widthMeasureSpec);
int height = measureDimension(dp2px(DEFAULT_SIZE), heightMeasureSpec);
setMeasuredDimension(width, height);
}
private int dp2px(int dpValue) {
return (int) getContext().getResources().getDisplayMetrics().density * dpValue;
}
private int measureDimension(int defaultSize, int measureSpec) {
int result = defaultSize;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(defaultSize, specSize);
} else {
result = defaultSize;
}
return result;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (!mHasAnimation) {
mHasAnimation = true;
initAnimation();
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float circleSpacing = 12;
float x = getWidth() / 2;
float y = getHeight() / 2;
canvas.save();
canvas.translate(x, y);
canvas.scale(scaleFloat1, scaleFloat1);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(0, 0, x / 2.5f, mPaint);
canvas.restore();
canvas.translate(x, y);
canvas.scale(scaleFloat2, scaleFloat2);
canvas.rotate(degrees);
mPaint.setStrokeWidth(3);
mPaint.setStyle(Paint.Style.STROKE);
float[] startAngles = new float[]{225, 45};
for (int i = 0; i < 2; i++) {
RectF rectF = new RectF(-x + circleSpacing, -y + circleSpacing, x - circleSpacing, y - circleSpacing);
canvas.drawArc(rectF, startAngles[i], 90, false, mPaint);
}
}
public void initAnimation() {
mAnimators = createAnimation();
}
public void setAnimationStatus(AnimStatus animStatus) {
if (mAnimators == null) {
return;
}
int count = mAnimators.size();
for (int i = 0; i < count; i++) {
Animator animator = mAnimators.get(i);
boolean isRunning = animator.isRunning();
switch (animStatus) {
case START:
if (!isRunning) {
animator.start();
}
break;
case END:
if (isRunning) {
animator.end();
}
break;
case CANCEL:
if (isRunning) {
animator.cancel();
}
break;
}
}
}
public enum AnimStatus {
START, END, CANCEL
}
public List<Animator> createAnimation() {
ValueAnimator scaleAnim = ValueAnimator.ofFloat(1, 0.3f, 1);
scaleAnim.setDuration(1000);
scaleAnim.setRepeatCount(-1);
scaleAnim.addUpdateListener(animation -> {
scaleFloat1 = (float) animation.getAnimatedValue();
postInvalidate();
});
scaleAnim.start();
ValueAnimator scaleAnim2 = ValueAnimator.ofFloat(1, 0.6f, 1);
scaleAnim2.setDuration(1000);
scaleAnim2.setRepeatCount(-1);
scaleAnim2.addUpdateListener(animation -> {
scaleFloat2 = (float) animation.getAnimatedValue();
postInvalidate();
});
scaleAnim2.start();
ValueAnimator rotateAnim = ValueAnimator.ofFloat(0, 180, 360);
rotateAnim.setDuration(1000);
rotateAnim.setRepeatCount(-1);
rotateAnim.addUpdateListener(animation -> {
degrees = (float) animation.getAnimatedValue();
postInvalidate();
});
rotateAnim.start();
List<Animator> animators = new ArrayList<>();
animators.add(scaleAnim);
animators.add(scaleAnim2);
animators.add(rotateAnim);
return animators;
}
}