package com.github.cai.greendaotaste.progress;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.LinearInterpolator;
import com.github.cai.greendaotaste.R;
/**
* Created by admin on 2017/6/6.
*/
public class ProgressWithPercent extends View {
public static final String TAG = ProgressWithPercent.class.getSimpleName();
public static final int DEFAULT_SMOOTH_FACTOR = 10;
//为了滑动更平滑
private int mSmoothFactor;
private int mProgressBackgroundColor, mProgressForegroundColor, mProgressTextColor;
private float mProgressTextSize;
private float mRoundRectRadius;
private float mPaddingRightProgress;
private int currentProgressWidth = 0, targetProgress, drawProgress = 0;
private int mAnimationDuration, mAnimationTimeStartDelay;
private Paint mProgressBackgroundPaint, mProgressForegroundPaint, mProgressTextPaint;
private ValueAnimator mValueAnimator;
private RectF mBackgroundRectF, mProgressRectF = new RectF();
public ProgressWithPercent(Context context) {
this(context, null);
}
public ProgressWithPercent(Context context, AttributeSet attrs) {
super(context, attrs);
initAttr(context, attrs);
initPaint();
initProgressAnimation();
}
private void initAttr(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ProgressWithPercent);
mProgressBackgroundColor = ta.getColor(R.styleable.ProgressWithPercent_progressBackground, Color.GRAY);
mProgressForegroundColor = ta.getColor(R.styleable.ProgressWithPercent_progressForeground, Color.YELLOW);
mProgressTextColor = ta.getColor(R.styleable.ProgressWithPercent_progressTextColor, Color.RED);
mProgressTextSize = ta.getDimensionPixelSize(R.styleable.ProgressWithPercent_progressTextSize, 18);
mPaddingRightProgress = ta.getDimensionPixelSize(R.styleable.ProgressWithPercent_progressTextPaddingToRight, 10);
mRoundRectRadius = ta.getDimensionPixelSize(R.styleable.ProgressWithPercent_progressRoundRectRadius, 10);
targetProgress = ta.getInt(R.styleable.ProgressWithPercent_progressTargetValue, 100);
mAnimationDuration = ta.getInt(R.styleable.ProgressWithPercent_progressAnimationTimeDuration, 3000);
mAnimationTimeStartDelay = ta.getInt(R.styleable.ProgressWithPercent_progressAnimationTimeStartDelay, 500);
mSmoothFactor = ta.getInt(R.styleable.ProgressWithPercent_progressSmoothFactor, DEFAULT_SMOOTH_FACTOR);
ta.recycle();
}
private void initPaint() {
mProgressBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mProgressBackgroundPaint.setStrokeWidth(1);
mProgressBackgroundPaint.setColor(mProgressBackgroundColor);
mProgressBackgroundPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mProgressBackgroundPaint.setStrokeCap(Paint.Cap.ROUND);
mProgressForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mProgressForegroundPaint.setStrokeWidth(1);
mProgressForegroundPaint.setColor(mProgressForegroundColor);
mProgressForegroundPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mProgressForegroundPaint.setStrokeCap(Paint.Cap.ROUND);
mProgressTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mProgressTextPaint.setTextSize(mProgressTextSize);
mProgressTextPaint.setColor(mProgressTextColor);
mProgressTextPaint.setStrokeWidth(1);
mProgressTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);
}
public void initProgressAnimation() {
mValueAnimator = ValueAnimator.ofInt(0, targetProgress * mSmoothFactor);
mValueAnimator.setDuration(mAnimationDuration);
mValueAnimator.setStartDelay(mAnimationTimeStartDelay);
mValueAnimator.setInterpolator(new LinearInterpolator());
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int progress = (int) animation.getAnimatedValue();
if (listener != null)
listener.progressStateChange(progress / mSmoothFactor);
drawProgress = progress / mSmoothFactor;
currentProgressWidth = progress * (getWidth() - getPaddingRight()) / (100 * mSmoothFactor);
invalidate();
}
});
mValueAnimator.start();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBackgroundRectF = new RectF(getPaddingLeft(), getPaddingTop(), w - getPaddingRight(), h - getPaddingBottom());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRoundRect(mBackgroundRectF, mRoundRectRadius, mRoundRectRadius, mProgressBackgroundPaint);
mProgressRectF.set(getPaddingLeft(), getPaddingTop(), currentProgressWidth, getMeasuredHeight() - getPaddingBottom());
canvas.drawRoundRect(mProgressRectF, mRoundRectRadius, mRoundRectRadius, mProgressForegroundPaint);
String drawString = String.format("%d%s", drawProgress, "%");
//得到文本的宽度
float textWidth = mProgressTextPaint.measureText(drawString);
float textX = currentProgressWidth - textWidth - mPaddingRightProgress;
Rect textRect = new Rect();
mProgressTextPaint.getTextBounds(drawString, 0, drawString.length() - 1, textRect);
//加上是因为绘制文本时是以文本底部为基线
float textY = (getMeasuredHeight() >> 1) + (textRect.height() >> 1);
if (textX - getPaddingLeft() > 0) {
canvas.drawText(drawString, textX, textY, mProgressTextPaint);
}else{
canvas.drawText(drawString, getPaddingLeft(), textY, mProgressTextPaint);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightSpecMode == MeasureSpec.AT_MOST){
DisplayMetrics metrics = new DisplayMetrics();
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(metrics);
int wrapContentHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, metrics);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(wrapContentHeight,MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void startProgressAnimation(){
if (mValueAnimator.isRunning()){
mValueAnimator.cancel();
}
mValueAnimator.start();
}
private ProgressListener listener;
public void setListener(ProgressListener listener) {
this.listener = listener;
}
interface ProgressListener {
void progressStateChange(int progress);
}
}