自定义渐变-圆角ProgressBar

先上进度条样式:

image.png

再上效果:

a939381496fdfec9824dce9612718455.gif

在平时开发中,常常遇到一些特殊需求,就比方我今天写的这篇。
UI设计让我必须搞一个圆角的进度条,虽然不是特别难,但本着方便你我,下次使用拿来主义,我今天花几分钟自定义一个。

说来也巧,在正常的开发时,发现只能对进度条的背景色设置圆角,进度条却始终是方的,令我百思不得姐~~

正式代码我放到最后

没错,我不想写了,这就是最后~~~~

实现最终代码

step1.自定义一个Progressbar
/**
 * Created by gudd on 2024/9/27.
 * 自定义该view,主要就是为了实现将进度条设置为圆角
 */
public class RoundedCornerProgressBar extends ProgressBar {
    private final Paint paint;
    private final RectF rectF;
    // 这两个颜色主要用来从resource中获取颜色,不至于将色值写死在自定义view中。
    private int progressColorStart = 0;
    private int progressColorEnd = 0;

    public CustomProgressBar(Context context) {
        this(context, null);
    }

    public CustomProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        paint = new Paint();
        rectF = new RectF();
        progressColorStart = ContextCompat.getColor(context, R.color.colorStart);
        progressColorEnd = ContextCompat.getColor(context, R.color.colorEnd);
        paint.setAntiAlias(true);
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        super.draw(canvas);

        float radius = 40f;
        float width = getWidth();
        float height = getHeight();


        // 设置圆角矩形区域
        rectF.set(0f, 0f, width * getProgress() / getMax(), height);
        // 设置渐变色,两种方法,喜欢哪种用哪种。
        /*paint.setShader(new LinearGradient(0f, 0f, width, 0f,
            progressColorStart, progressColorEnd, Shader.TileMode.CLAMP));*/
        paint.setShader(new LinearGradient(0f, 0f, width, 0f,
                Color.parseColor("#FF5722"), Color.parseColor("#FFC107"), Shader.TileMode.CLAMP));

        canvas.drawRoundRect(rectF, radius, radius, paint); // 绘制圆角矩形
    }

    // 设置连续动画,从左往右类似加载
    public void setProgressWithAnimation(int progress, long duration) {
        ObjectAnimator animator = ObjectAnimator.ofInt(this, "progress", this.getProgress(), progress);
        animator.setDuration(duration);
        animator.start();
    }
}
step2.创建一个drawable,用来设置progressbar的背景,其实也可以写到自定义view中,但我这里为了方便就写在xml里了,因为这个比较简单,不像圆角进度条一样圆角显示异常。

创建一个drawable文件叫:custom_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="20dp" />
            <solid android:color="#e0e0e0" />
        </shape>
    </item>
    <!-- 下面这边注释主要是因为这段虽然可以设置进度条渐变色,但并不能显示圆角,这让我不得不把它写在注释里面-->
    <!--<item android:id="@android:id/progress">
        <clip>
            <shape >
                <corners android:radius="20dp" /> &lt;!&ndash; 圆角 &ndash;&gt;
                <gradient
                    android:startColor="#FF5722"
                    android:endColor="#FFC107"
                    android:angle="0"/> &lt;!&ndash; 渐变色 &ndash;&gt;
            </shape>
        </clip>
    </item>-->
</layer-list>
step3.在自己的布局中添加这个自定义view,并设置drawable背影
<com.gudd.importmodulepreview.CustomProgressBar
        android:id="@+id/customProgressBar"
        android:layout_width="0dp"
        android:layout_height="20dp"
        android:layout_margin="16dp"
        android:max="100"
        android:progress="0"
        android:progressDrawable="@drawable/custom_progress"   // 这一行就是我设置的背景
        style="?android:attr/progressBarStyleHorizontal"       // 这一行需要小心,不设置则有可能不是横向进度条样式
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:indeterminate="false"/>                         //这个确保 indeterminate="false",否则进度条将会显示为转圈样式
step4.在MainActivity.java中设置进度。可以有动画效果
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        CustomProgressBar progressBar = findViewById(R.id.customProgressBar);

        progressBar.postDelayed(()->{
            progressBar.setProgressWithAnimation(80, 1000); // 设置动画时长为 1 秒,进度为 80
        },2000);
    }
}

接上部分继续优化

优化需求

根据上面已经实现的部分,如今又来一个新界面,该界面的圆角又不是需要那么圆了,需要带点方的圆角,具体描述说也说不清楚,上个图吧,就像下面这图一样,不要太圆的圆角:


image.png

所以目前为了实现该功能总不能再写一个类对吧,这里修改下代码,让它变为动态设置,写在xml上,如果谁需要写个方法告诉我,我加上,这次不加是因为我比较懒!!!
对了,这次把动态设置背景的也给加上。
注意:该类设置了动态背景后,将不能使用(提前说明)

// 设置该属性将无效
android:progressDrawable="@drawable/custom_progress_drawable"了。

首先需要加一个“declare-styleable”

step1:在资源目录的res/values/attrs中增加代码,没有attrs需要创建一个
<declare-styleable name="RoundedCornerProgressBar">
        <attr name="progressBarBackground" format="reference|color" />
        <attr name="progressColorStart" format="reference|color" />
        <attr name="progressColorEnd" format="reference|color" />
        <attr name="progressRadius" format="dimension" />
</declare-styleable>
step2:修改自定义View
/**
 * Created by gudd on 2024/9/27.
 * 该自定义view在使用中将使{android:progressDrawable="@drawable/custom_progress"}设置无效。
 * 注:设置背景请使用app:progressBarBackground="#FFFFFF"或app:progressBarBackground="@color/red"
 */
public class RoundedCornerProgressBar extends ProgressBar {
    private final Paint paint;
    private final Paint paintBg;    // 增加
    private final RectF rectF;
    private final RectF rectFBg;    // 增加
    private final int progressBarBackground;    // 增加
    private final int progressColorStart;    // 增加
    private final int progressColorEnd;    // 增加
    private final float progressRadius;    // 增加

    public RoundedCornerProgressBar(Context context) {
        this(context, null);
    }

    public RoundedCornerProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundedCornerProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        setProgressDrawable(null); // 增加  去除默认背景
        paint = new Paint();
        paintBg = new Paint();    // 增加
        rectF = new RectF();
        rectFBg = new RectF();    // 增加
        paint.setAntiAlias(true);

        // 增加,这部分使用try-with-resources语句,执行到末尾自动关闭typedArray,
        // 如果报错,请使用:try{}finally{}语句
        try (TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundedCornerProgressBar)) {
            progressBarBackground = typedArray.getColor(R.styleable.RoundedCornerProgressBar_progressBarBackground, Color.GRAY);
            progressColorStart = typedArray.getColor(R.styleable.RoundedCornerProgressBar_progressColorStart, Color.parseColor("#FFC107"));
            progressColorEnd = typedArray.getColor(R.styleable.RoundedCornerProgressBar_progressColorEnd, Color.parseColor("#FF5722"));
            progressRadius = typedArray.getDimension(R.styleable.RoundedCornerProgressBar_progressRadius, 16.f);
        }

    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        super.draw(canvas);

        float radius = progressRadius;     // 修改这行
        float width = getWidth();
        float height = getHeight();

        // 增加 绘制背景
        paintBg.setColor(progressBarBackground);
        rectFBg.set(0f, 0f, width, height);
        canvas.drawRoundRect(rectFBg, radius, radius, paintBg); // 绘制圆角背景

        // 设置圆角矩形区域
        rectF.set(0f, 0f, width * getProgress() / getMax(), height);
        // 设置渐变色
        paint.setShader(new LinearGradient(0f, 0f, width, 0f,
                progressColorStart, progressColorEnd, Shader.TileMode.CLAMP));
        canvas.drawRoundRect(rectF, radius, radius, paint); // 绘制圆角矩形
    }

    public void setProgressWithAnimation(int progress, long duration) {
        ObjectAnimator animator = ObjectAnimator.ofInt(this, "progress", this.getProgress(), progress);
        animator.setDuration(duration);
        animator.start();
    }
}
step3:在布局中使用
<com.gudd.importmodulepreview.RoundedCornerProgressBar
        android:id="@+id/customProgressBar"
        android:layout_width="0dp"
        android:layout_height="20dp"
        android:layout_margin="16dp"
        android:max="100"
        android:progress="0"
        android:progressDrawable="@drawable/custom_progress"  // 该行设置将无效,请删除该行
        style="?android:attr/progressBarStyleHorizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:indeterminate="false"
        app:progressColorStart="#FFC107"   // 进度条起点色
        app:progressColorEnd="#FF5722"    // 进度条终点色
        app:progressBarBackground="#e2e2e2"  // 进度条背景色
        app:progressRadius="20dp"/>      // 进度条背景和前景的圆角度数

完!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容