package com.basic.security.widget;
|
|
import android.annotation.SuppressLint;
|
import android.content.Context;
|
import android.content.res.TypedArray;
|
import android.graphics.Canvas;
|
import android.graphics.Color;
|
import android.graphics.Matrix;
|
import android.graphics.Paint;
|
import android.graphics.RectF;
|
import android.graphics.Shader;
|
import android.graphics.SweepGradient;
|
import android.support.annotation.Nullable;
|
import android.util.AttributeSet;
|
import android.util.TypedValue;
|
import android.view.View;
|
import android.view.animation.Animation;
|
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.Transformation;
|
|
public class ClusterRoundView extends View implements Animation.AnimationListener {
|
private float mSweepAngle = 1;
|
private float mOldAngle = 0;
|
private float mNewAngle = 0;
|
private float mRingWidth = 0;
|
private int mRingColor = 0;
|
private float mProgressRingWidth = 0;
|
private int mProgressRingStartColor = 0;
|
private int mProgressRingEndColor = 0;
|
private float mRadius = 0;
|
private Paint mProgressRingPaint;
|
private Shader mProgressRingShader;
|
private Paint mRingPaint;
|
private Paint mTextPaint;
|
private int mTextColor;
|
private float mTextSize;
|
private int[] arcColors = {};
|
private BarAnimation barAnimation;
|
private ScaleAnimation scaleAnimation;
|
private boolean isAnimation = false;
|
|
public ClusterRoundView(Context context) {
|
this(context, null);
|
}
|
|
public ClusterRoundView(Context context, AttributeSet attrs) {
|
this(context, attrs, 0);
|
}
|
|
public ClusterRoundView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
this(context, attrs, defStyleAttr, 0);
|
}
|
|
public ClusterRoundView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
super(context, attrs, defStyleAttr);
|
TypedArray typedArray = context.obtainStyledAttributes(attrs, com.basic.security.utils.RUtils.R_styleable_ClusterRoundView);
|
mRingWidth = typedArray.getDimension(com.basic.security.utils.RUtils.R_styleable_ClusterRoundView_ring_width, 0);
|
mRingColor = typedArray.getColor(com.basic.security.utils.RUtils.R_styleable_ClusterRoundView_ring_color, Color.parseColor("#CBCBCB"));
|
mProgressRingWidth = typedArray.getDimension(com.basic.security.utils.RUtils.R_styleable_ClusterRoundView_progress_ring_width, 0);
|
mProgressRingStartColor = typedArray.getColor(com.basic.security.utils.RUtils.R_styleable_ClusterRoundView_progress_ring_start_color, Color.parseColor("#086ab5"));
|
mProgressRingEndColor = typedArray.getColor(com.basic.security.utils.RUtils.R_styleable_ClusterRoundView_progress_ring_end_color, Color.parseColor("#21cbe2"));
|
mRadius = typedArray.getDimension(com.basic.security.utils.RUtils.R_styleable_ClusterRoundView_android_radius, 0);
|
mTextColor = typedArray.getColor(com.basic.security.utils.RUtils.R_styleable_ClusterRoundView_text_color, Color.parseColor("#086ab5"));
|
mTextSize = typedArray.getDimension(com.basic.security.utils.RUtils.R_styleable_ClusterRoundView_text_size, dp2px(context, 40));
|
typedArray.recycle();
|
init();
|
}
|
|
@Override
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
}
|
|
@Override
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
super.onLayout(changed, left, top, right, bottom);
|
}
|
|
private void init() {
|
mRingPaint = new Paint();
|
mRingPaint.setAntiAlias(true);
|
mRingPaint.setStyle(Paint.Style.STROKE);
|
mRingPaint.setColor(mRingColor);
|
arcColors = new int[]{mProgressRingStartColor, mProgressRingEndColor};
|
mProgressRingPaint = new Paint();
|
mProgressRingPaint.setAntiAlias(true);
|
mProgressRingPaint.setStyle(Paint.Style.STROKE);
|
mProgressRingPaint.setStrokeWidth(mProgressRingWidth);
|
mTextPaint = new Paint();
|
mTextPaint.setAntiAlias(true);
|
mTextPaint.setStyle(Paint.Style.FILL);
|
mTextPaint.setTextAlign(Paint.Align.CENTER);
|
mTextPaint.setColor(mTextColor);
|
mTextPaint.setTextSize(mTextSize);
|
barAnimation = new BarAnimation();
|
barAnimation.setAnimationListener(this);
|
scaleAnimation = new ScaleAnimation();
|
scaleAnimation.setDuration(100);
|
}
|
|
public void setAngle(final float newAngle) {
|
setAngle(newAngle, true);
|
}
|
|
public void setAngle(final float newAngle, boolean isScale) {
|
if (!isAnimation) {
|
if (isScale) {
|
scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
|
public void onAnimationStart(Animation animation) {
|
}
|
|
public void onAnimationEnd(Animation animation) {
|
changeAngle(newAngle);
|
}
|
|
public void onAnimationRepeat(Animation animation) {
|
}
|
});
|
startAnimation(scaleAnimation);
|
} else {
|
changeAngle(newAngle);
|
}
|
}
|
}
|
|
private void changeAngle(float newAngle) {
|
mOldAngle = mNewAngle;
|
mNewAngle = newAngle;
|
int duration = (int) (Math.abs(mNewAngle - mOldAngle) * 15);
|
barAnimation.setDuration(duration);
|
barAnimation.setInterpolator(new DecelerateInterpolator());
|
startAnimation(barAnimation);
|
}
|
|
@SuppressLint("DrawAllocation")
|
public void onDraw(Canvas canvas) {
|
float x = getWidth() / 2;
|
float y = getHeight() / 2;
|
float radius = mRadius == 0 ? Math.min(getWidth() / 2, getHeight() / 2) : mRadius;
|
float ringWidth = mRingWidth == 0 ? radius / 5 : mRingWidth;
|
radius = radius - ringWidth / 2;
|
mRingPaint.setStrokeWidth(ringWidth);
|
canvas.drawCircle(x, y, radius, mRingPaint);
|
if (mProgressRingShader == null) {
|
mProgressRingShader = new SweepGradient(x, y, arcColors, null);
|
mProgressRingPaint.setShader(mProgressRingShader);
|
}
|
float progressRingWidth = mProgressRingWidth == 0 ? ringWidth : mProgressRingWidth;
|
mProgressRingPaint.setStrokeWidth(progressRingWidth);
|
float left = x - radius;
|
float top = y - radius;
|
float right = x + radius;
|
float bottom = y + radius;
|
double radian = radianToAngle(radius);
|
double degrees = Math.toDegrees(-2 * Math.PI / 360 * (90 + radian));
|
canvas.save();
|
canvas.rotate((float) degrees, x, y);
|
canvas.drawArc(new RectF(left, top, right, bottom), (float) radian, mOldAngle + mSweepAngle, false, mProgressRingPaint);
|
canvas.restore();
|
int percentage = (int) ((mOldAngle + mSweepAngle) / 360 * 100);
|
float sizeHeight = getFontHeight();
|
canvas.drawText(percentage + "%", x, y + sizeHeight / 2, mTextPaint);
|
super.onDraw(canvas);
|
}
|
|
public float getFontHeight() {
|
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
|
return fm.descent - fm.ascent;
|
}
|
|
private double radianToAngle(float radios) {
|
double aa = mProgressRingWidth / 2 / radios;
|
double asin = Math.asin(aa);
|
return Math.toDegrees(asin);
|
}
|
|
public void onAnimationStart(Animation animation) {
|
isAnimation = true;
|
}
|
|
public void onAnimationEnd(Animation animation) {
|
isAnimation = false;
|
}
|
|
public void onAnimationRepeat(Animation animation) {
|
}
|
|
private int dp2px(Context context, float dpVal) {
|
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
|
dpVal, context.getResources().getDisplayMetrics());
|
}
|
|
public class ScaleAnimation extends Animation {
|
private int centerX;
|
private int centerY;
|
|
public ScaleAnimation() {
|
}
|
|
public void initialize(int width, int height, int parentWidth,
|
int parentHeight) {
|
super.initialize(width, height, parentWidth, parentHeight);
|
centerX = width / 2;
|
centerY = height / 2;
|
}
|
|
protected void applyTransformation(float interpolatedTime, Transformation t) {
|
super.applyTransformation(interpolatedTime, t);
|
if (interpolatedTime < 0.25f) {
|
float ss = interpolatedTime * 0.4f + 1f;
|
Matrix matrix = t.getMatrix();
|
matrix.setScale(ss, ss, centerX, centerY);
|
} else if (interpolatedTime >= 0.25f && interpolatedTime < 0.5f) {
|
float ss = (0.5f - interpolatedTime) * 0.4f + 1f;
|
Matrix matrix = t.getMatrix();
|
matrix.setScale(ss, ss, centerX, centerY);
|
} else if (interpolatedTime >= 0.5f && interpolatedTime < 0.75f) {
|
float ss = (0.75f - interpolatedTime) * 0.4f + 0.9f;
|
Matrix matrix = t.getMatrix();
|
matrix.setScale(ss, ss, centerX, centerY);
|
} else if (interpolatedTime >= 0.75f && interpolatedTime <= 1f) {
|
float ss = interpolatedTime * 0.4f + 0.6f;
|
Matrix matrix = t.getMatrix();
|
matrix.setScale(ss, ss, centerX, centerY);
|
}
|
}
|
}
|
|
public class BarAnimation extends Animation {
|
public BarAnimation() {
|
}
|
|
protected void applyTransformation(float interpolatedTime,
|
Transformation t) {
|
super.applyTransformation(interpolatedTime, t);
|
if (mNewAngle - mOldAngle >= 0) {
|
mSweepAngle = interpolatedTime * (mNewAngle - mOldAngle);
|
} else {
|
mSweepAngle = interpolatedTime * (mNewAngle - mOldAngle);
|
}
|
postInvalidate();
|
}
|
}
|
}
|