效果图
废话不多说,直接上一张
gif图有点暗,可能是截图软件的原因,来个静态的效果,里面是有个背景的噢
简单介绍
一个圆角的渐变色progress的效果,加载时能从0增长到targetCount(如果需要改变颜色,直接在
private static final int[] SECTION_COLORS = {Color.parseColor("#FF62EBEE"), Color.parseColor("#FF50E2FB"), Color.parseColor("#FF4CE1FD")};
这里改下就ok了,自定义你懂得,自己改改就好了)
如何用这个效果
- 在xml中使用该自定义控件
- 设置最大值
setMaxCount(float maxCount)
- 设置当前显示值
setTargetCount(float targetCount)
上代码
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
/***
* 自定义进度条
*
* @author spring sky
* Email:vipa1888@163.com
* 创建时间:2014-1-6下午3:28:51
* @updatedauthor stefan
* 修改时间:2016-12-19下午1:43:03
*/
public class SpringProgressView extends View {
/**
* 分段颜色
*/
private static final int[] SECTION_COLORS = {Color.parseColor("#FF62EBEE"), Color.parseColor("#FF50E2FB"), Color.parseColor("#FF4CE1FD")};
/**
* 进度条最大值
*/
private float maxCount;
/**
* 进度条当前值
*/
private float currentCount = 0;
/**
* 目标值
*/
private float targetCount;
private int mBackGroundColor = Color.parseColor("#26000000");
/**
* 当前背景宽
*/
private float mCurrentBgWidth = 0;
/**
* 当前背景高度
*/
private float mCurrentBgHeight = 0;
/**
* 画笔
*/
private Paint mPaint, mBgPaint;
private int mWidth, mHeight;
float speed = 20f, bgSpeed = 2f;
private Object[] mLock = new Object[]{};
private boolean needShowBgAnimDelay;
private long DURATION;
public SpringProgressView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
public SpringProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public SpringProgressView(Context context) {
super(context);
initView(context);
}
private void initView(Context context) {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.rgb(71, 76, 80));
mBgPaint = new Paint();
mBgPaint.setAntiAlias(true);
mBgPaint.setColor(mBackGroundColor);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int round = (int) (mCurrentBgHeight / 2);
RectF rectBlackBg = new RectF(0, 0, mCurrentBgWidth, mCurrentBgHeight);
canvas.drawRoundRect(rectBlackBg, round, round, mBgPaint);
float section = currentCount / maxCount;
RectF rectProgressBg = new RectF(0, 0, mWidth * section, mCurrentBgHeight);
if (section <= 1.0f / 3.0f) {
if (section != 0.0f) {
mPaint.setColor(SECTION_COLORS[0]);
} else {
mPaint.setColor(Color.TRANSPARENT);
}
} else {
int count = (section <= 1.0f / 3.0f * 2) ? 2 : 3;
int[] colors = new int[count];
System.arraycopy(SECTION_COLORS, 0, colors, 0, count);
float[] positions = new float[count];
if (count == 2) {
positions[0] = 0.0f;
positions[1] = 1.0f - positions[0];
} else {
positions[0] = 0.0f;
positions[1] = (maxCount / 3) / currentCount;
positions[2] = 1.0f - positions[0] * 2;
}
positions[positions.length - 1] = 1.0f;
LinearGradient shader = new LinearGradient(0, 0, mWidth * section, mCurrentBgHeight, colors, null, Shader.TileMode.MIRROR);
mPaint.setShader(shader);
}
canvas.drawRoundRect(rectProgressBg, round, round, mPaint);
}
private int dipToPx(int dip) {
float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));
}
/***
* 设置最大的进度值
*
* @param maxCount
*/
public void setMaxCount(float maxCount) {
this.maxCount = maxCount;
}
/***
* 设置当前的进度值
*
* @param currentCount
*/
private void setCurrentCount(float currentCount) {
synchronized (mLock) {
this.currentCount = currentCount > targetCount ? targetCount : currentCount;
invalidate();
}
}
/***
* 设置当前的进度值
*
* @param currentCount
*/
private void setCurrentBgWidth(float currentCount) {
synchronized (mLock) {
this.mCurrentBgWidth = currentCount > mWidth ? mWidth : currentCount;
invalidate();
}
}
/***
* 设置当前的进度值
*
* @param currentCount
*/
private void setCurrentBgHeight(float currentCount) {
synchronized (mLock) {
this.mCurrentBgHeight = currentCount > mHeight ? mHeight : currentCount;
invalidate();
}
}
public float getTargetCount() {
return targetCount;
}
public float getMaxCount() {
return maxCount;
}
public float getCurrentCount() {
return currentCount;
}
public void setTargetCount(float targetCount) {
if (targetCount != 0 && targetCount < 10) targetCount = 10;//为了显示效果
this.targetCount = targetCount > maxCount ? maxCount : targetCount;
reset();
ValueAnimator animator = ValueAnimator.ofFloat(currentCount, targetCount);
animator.setInterpolator(new AccelerateDecelerateInterpolator());
DURATION = (long) (targetCount * speed);
animator.setDuration(DURATION);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentCount = (float) animation.getAnimatedValue();
mHandler.sendEmptyMessageDelayed(1, 100);
}
});
animator.start();
if (mHeight != 0) {
startBgAnim();
} else needShowBgAnimDelay = true;
}
private void startBgAnim() {
needShowBgAnimDelay = false;
ValueAnimator animatorWidth = ValueAnimator.ofFloat(mCurrentBgWidth, mWidth);
animatorWidth.setInterpolator(new AccelerateDecelerateInterpolator());
animatorWidth.setDuration((long) ((mWidth) * bgSpeed));
animatorWidth.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurrentBgWidth = (float) animation.getAnimatedValue();
mHandler.sendEmptyMessageDelayed(2, 100);
}
});
animatorWidth.start();
ValueAnimator animatorHeight = ValueAnimator.ofFloat(mCurrentBgHeight, mHeight);
animatorHeight.setInterpolator(new AccelerateDecelerateInterpolator());
animatorHeight.setDuration((long) ((mWidth) * bgSpeed));
animatorHeight.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurrentBgHeight = (float) animation.getAnimatedValue();
mHandler.sendEmptyMessageDelayed(3, 100);
}
});
animatorHeight.start();
}
private void reset() {
currentCount = 0;
mCurrentBgWidth = 0;
mCurrentBgHeight = 0;
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) {
mWidth = widthSpecSize;
} else {
mWidth = 0;
}
if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) {
mHeight = dipToPx(15);
} else {
mHeight = heightSpecSize;
}
setMeasuredDimension(mWidth, mHeight);
if (needShowBgAnimDelay)
startBgAnim();
}
private Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
setCurrentCount(currentCount);
break;
case 2:
setCurrentBgWidth(mCurrentBgWidth);
break;
case 3:
setCurrentBgHeight(mCurrentBgHeight);
break;
}
}
};
}