ValueAnimator的使用,具体产考文档:ValueAnimator 基本使用
ScaleDrawable的使用。具体参考文档:ScaleDrawable的使用
先从主界面布局开始看起
"@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_margin="10dp"
android:max="100"
android:progress="20"
android:progressDrawable="@drawable/layer_list_progress_drawable" />
在看的progressDrawable布局: layer_list_progress_drawable_1.xml,记住这个scale,非常重要,接下来在代码实现会用到ScaleDrawable这个类
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@android:id/background"
android:drawable="@drawable/shape_progressbar_bg" />
<item android:id="@android:id/progress">
<scale
android:drawable="@drawable/shape_progressbar_progress"
android:scaleWidth="100%" />
item>
layer-list>
下面是背景,和进度文件: shape_progressbar_bg.xml ,shape_progressbar_progress.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="10dp" />
<solid android:color="#e2e2e2" />
shape>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="10dp" />
<solid android:color="#f25252" />
shape>
以上代码实现参考了:原文链接,有兴趣的请支持原创
public class HorizontalProgressBar extends ProgressBar {
private static final String TAG = HorizontalProgressBar.class.getName();
private static final long DEFAULT_DURATION = 1000;
private static final int DEFAULT_CORNER_RADIUS = 10;
private static final int DEFAULT_PROGRESS_COLOR = Color.parseColor("#FF0000");
private static final int DEFAULT_PROGRESS_BACKGROUND_COLOR = Color.parseColor("#FFFFFF");
private ValueAnimator mProgressAnimator;
private boolean isAnimating = false;
public HorizontalProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public HorizontalProgressBar(Context context) {
this(context, null, 0);
}
public HorizontalProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, 0);
setUpAnimator();
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.HorizontalProgressBar);
int progressColor = DEFAULT_PROGRESS_COLOR;
int backgroundColor = DEFAULT_PROGRESS_COLOR;
int cornerRadius = DEFAULT_CORNER_RADIUS;
if(typedArray != null && typedArray.getIndexCount() > 0){
progressColor = typedArray.getColor(R.styleable.HorizontalProgressBar_progressColor, DEFAULT_PROGRESS_COLOR);
backgroundColor = typedArray.getColor(R.styleable.HorizontalProgressBar_backgroundColor, DEFAULT_PROGRESS_COLOR);
cornerRadius = typedArray.getDimensionPixelSize(R.styleable.HorizontalProgressBar_cornerRadius, DEFAULT_CORNER_RADIUS);
}
ScaleDrawable progressClipDrawable;
Drawable[] progressDrawables;
/****
* 使用ScaleDrawable可以实现进度条也是圆角的,使用ClipDrawable则右边的进度条显示的是直角的。
*/
progressClipDrawable = new ScaleDrawable(
createGradientDrawable(progressColor, cornerRadius),
Gravity.LEFT,
1F,0F);
progressDrawables = new Drawable[]{
createGradientDrawable(backgroundColor, cornerRadius),
progressClipDrawable};
/****
* 类似于为Progresbar设置圆角的背景
*/
LayerDrawable progressLayerDrawable = new LayerDrawable(progressDrawables);
progressLayerDrawable.setId(0, android.R.id.background);
progressLayerDrawable.setId(1, android.R.id.progress);
super.setProgressDrawable(progressLayerDrawable);
if(typedArray != null){
typedArray.recycle();
}
}
private GradientDrawable createGradientDrawable(int color, int radius) {
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
gradientDrawable.setColor(color);
gradientDrawable.setCornerRadius(radius);
return gradientDrawable;
}
private void setUpAnimator() {
mProgressAnimator = new ValueAnimator();
mProgressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
HorizontalProgressBar.super.setProgress((Integer) animation.getAnimatedValue());
}
});
mProgressAnimator.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
isAnimating = true;
}
@Override
public void onAnimationEnd(Animator animation) {
isAnimating = false;
}
});
mProgressAnimator.setEvaluator(new IntEvaluator());
mProgressAnimator.setInterpolator(new LinearInterpolator());
mProgressAnimator.setDuration(DEFAULT_DURATION);
}
public void setProgressWithAnim(int progress) {
if (isAnimating) {
return;
}
if (mProgressAnimator == null) {
setUpAnimator();
}
mProgressAnimator.setIntValues(getProgress(), progress);
mProgressAnimator.start();
}
@Override
public void setProgressDrawable(Drawable d) {
// do Nothing
super.setProgressDrawable(d);
}
@Override
public synchronized void setProgress(int progress) {
if (!isAnimating) {
super.setProgress(progress);
}
}
@Deprecated
@Override
public synchronized void setSecondaryProgress(int secondaryProgress) {
// do Nothing
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mProgressAnimator != null) {
mProgressAnimator.cancel();
}
}
public void cancelAnimation() {
if (!isAnimating) {
return;
}
if (mProgressAnimator != null) {
mProgressAnimator.cancel();
}
isAnimating = false;
}
@Override
public synchronized void setMax(int max) {
if (!isAnimating) {
super.setMax(max);
}
}
private abstract class SimpleAnimatorListener implements Animator.AnimatorListener {
@Override
public abstract void onAnimationStart(Animator animation);
@Override
public abstract void onAnimationEnd(Animator animation);
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
}
}
<com.XXXXXXX.view.HorizontalProgressBar
android:layout_width="match_parent"
android:layout_height="10.0dp"
android:layout_marginTop="5dp"
android:visibility="visible"
HorizontalProgressBar:backgroundColor="@color/colorPrimaryDark"
HorizontalProgressBar:cornerRadius="10dp"
HorizontalProgressBar:progressColor="@color/colorAccent" />