Progress bar with adjustable gradient Progress
As shown in FIG
Demand scenario:
- progress bar
- Color gradient
- Can be static \ can be automatic
Code analysis
- Initialize the background progress bar brush and the foreground gradient progress bar brush
/**
初始化背景进度条画笔、前景可渐变进度条画笔
**/
private void initView(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ProgressCirce);
gradientLeftColor = typedArray.getColor(R.styleable.ProgressCirce_gradient_left_color, -1);
gradientRightColor = typedArray.getColor(R.styleable.ProgressCirce_gradient_right_color, -1);
normalColor = typedArray.getColor(R.styleable.ProgressCirce_gradient_normal_color, 0xFFF4F4F6);
backPaint = new Paint();
backPaint.setStyle(Paint.Style.FILL);
backPaint.setColor(normalColor);
backPaint.setAntiAlias(true);
forPaint = new Paint();
forPaint.setAntiAlias(true);
forPaint.setStyle(Paint.Style.FILL);
typedArray.recycle();
// forPaint.setColor(Color.RED);
}
- Use path to initialize the background progress path
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
forPath = new Path();
backPath = new Path();
backPath.addRoundRect(
getPaddingLeft(),
getPaddingTop(),
getMeasuredWidth(),
getMeasuredHeight(),
radius, radius, Path.Direction.CCW);
}
- Draw
By passing in the current progress and progressMax (maximum value), calculate where the current progress is in width,
get the stop position stopD, and draw the foreground progress
forPath.reset();
canvas.drawPath(backPath, backPaint);
float stopD = (float) (Math.abs(progress)) / progressMax * getMeasuredWidth();
forPaint.setShader(getLinearGradient());
forPath.addRoundRect(
getPaddingLeft(),
getPaddingTop(),
stopD,
getMeasuredHeight(),
radius, radius, Path.Direction.CCW);
if (progress != 1) {
canvas.drawPath(forPath, forPaint);
}
- Linear gradient
Get the linear gradient value, notify the incoming color id, and set the gradient.
/**
* 获取线性渐变
*
* @return
*/
private LinearGradient getLinearGradient() {
if (linearGradient == null) {
linearGradient = new LinearGradient(0, 0,
getMeasuredWidth(),
getMeasuredHeight(),
gradientLeftColor,
gradientRightColor,
Shader.TileMode.CLAMP); //根据R文件中的id获取到color
}
return linearGradient;
}
- Turn on dynamic progress animation
/**
* 开启自动进度动画
*/
public void startAutoProcessAnimation(final AnimationInterface animationInterface) {
if (valueAnimator == null) {
valueAnimator = ValueAnimator.ofInt(0, (int) progressMax);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
setProgress((Integer) animation.getAnimatedValue());
if (animationInterface != null) {
animationInterface.animationRunning((Integer) animation.getAnimatedValue());
}
}
});
valueAnimator.setDuration(2000);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.start();
}
}
/**
* 停止自动进度动画
*/
public void stopAutoProcessAnimation() {
if (valueAnimator != null) {
valueAnimator.cancel();
valueAnimator = null;
}
}
public interface AnimationInterface {
void animationRunning(int progress);
}
- Set static progress
/**
* 设置静态progress
*
* @param progress
*/
public void setProgress(int progress) {
if (progress > progressMax) {
this.progress = (int) progressMax;
} else if (progress <= 0) {
this.progress = 1;
} else {
this.progress = progress;
}
invalidate();
}