先上进度条样式:
再上效果:
在平时开发中,常常遇到一些特殊需求,就比方我今天写的这篇。
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" /> <!– 圆角 –>
<gradient
android:startColor="#FF5722"
android:endColor="#FFC107"
android:angle="0"/> <!– 渐变色 –>
</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);
}
}
接上部分继续优化
优化需求
根据上面已经实现的部分,如今又来一个新界面,该界面的圆角又不是需要那么圆了,需要带点方的圆角,具体描述说也说不清楚,上个图吧,就像下面这图一样,不要太圆的圆角:
所以目前为了实现该功能总不能再写一个类对吧,这里修改下代码,让它变为动态设置,写在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"/> // 进度条背景和前景的圆角度数