自定义ProgressBar实现两端都是圆角,并且带有Animation。

1.实现效果

这里写图片描述

2.使用到的知识点

ValueAnimator的使用,具体产考文档:ValueAnimator 基本使用

ScaleDrawable的使用。具体参考文档:ScaleDrawable的使用

3.通用的做法使用Style实现

3.1自定义 ProgressBar

先从主界面布局开始看起

 "@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" />

3.2 progressDrawable布局

在看的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>

3.3背景,和进度文件

下面是背景,和进度文件: 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>

以上代码实现参考了:原文链接,有兴趣的请支持原创

4.代码实现

4.1自定义ProgressBar

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) {

        }
    }
}

4.2如何使用

 <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" />

你可能感兴趣的:(android,ProgressBar)