根据公司UI要求,需要设计一个进度条,竖直的从上往下显示进度。效果图如下:
android中自定义view,一般指这三种方式:
- 继承自android原生的控件,如ProgressBar,ListView等;
- 组合控件,将多个控件组合起来;
- 完全自定义控件,继承自View。
最开始想通过自定义原生的ProgressBar或者SeekBar实现,但是大家都知道,
ProgressBar:是不跟用户交互的,只提供显示任务进度的作用。ProgressBar样式风格有大约6种,但基本上就两种:旋转进度条和水平进度条,而也只有水平进度条才可以设置进度的递增,其他的风格只是一个循环的动画。重写ProgressBar可以让它变为竖直,但我没找到让它从上往下显示进度的方法(默认从左往右变为竖直后是从下往上),就放弃这种方式了(如果读者有实现这种方式的方法,恳请告知我一下【谢谢】)。
SeekBar:是ProgressBar的子类,有一个拖动条,可以拖动控制进度,但不太不符合公司需求就不再多琢磨了。
于是乎,进入正题,通过继承View来自定义UI实现需求。
------------------------------------------------------
下面手把手使用,并附上代码:
1、继承view
/**
* 参考:https://blog.csdn.net/u013346208/article/details/83622599
*/
public class VerticalProgress extends View {
private int mRadius; //进度条圆角
private int mEndResId; // 进度条颜色
private int mProgressBgColorId; //进度条背景填充色
private int mBorderWidth; //边框宽度
private int progress = 0; // 默认进度
private int maxProgress = 100; // 最大进度值
private int mWidth;
private int mHeight;
private RectF mRectF;
private Paint mPaint;
public VerticalProgress(Context context) {
super(context);
init(context, null);
}
public VerticalProgress(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getMeasuredWidth() - 1;// 宽度值
mHeight = getMeasuredHeight() - 1;// 高度值
}
@SuppressLint("CustomViewStyleable")
private void init(Context context, AttributeSet attrs) {
TypedArray typedArray = null;
if (attrs != null) {
typedArray = context.obtainStyledAttributes(attrs, R.styleable.verticalProgress);
mRadius = typedArray.getInt(R.styleable.verticalProgress_progress_radius, 0);
mProgressBgColorId = typedArray.getResourceId(R.styleable.verticalProgress_progress_solid_color, R.color.progress_bg);
mEndResId = typedArray.getResourceId(R.styleable.verticalProgress_progress_end_color, R.color.progress_fg);
mBorderWidth = typedArray.getResourceId(R.styleable.verticalProgress_progress_border_width, 10);
}
if (typedArray != null) {
typedArray.recycle();
}
mRectF = new RectF();
mPaint = new Paint();
mPaint.setAntiAlias(true);
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 两端圆角弧度,为高度的一半
if (mRadius == 0) {
mRadius = mWidth / 2;
}
// 画背景层
mPaint.setColor(getResources().getColor(mProgressBgColorId));
mRectF.set(mBorderWidth, mBorderWidth, mWidth - mBorderWidth, mHeight - mBorderWidth);
canvas.drawRoundRect(mRectF, mRadius, mRadius, mPaint);
// 画进度层
if (progress == 0)//进度为0时,不画进度
return;
mPaint.setColor(getResources().getColor(mEndResId)); // 修改进度层颜色
mRectF.set(10, 0, mWidth - 10, progress / 100f * mHeight); // 修改进度层宽度:从上往下
// mRectF.set(+10, mHeight - progress / 100f * mHeight + 10, mWidth - 10, mHeight - 10); // 修改进度层宽度:从下往上
canvas.drawRoundRect(mRectF, mRadius, mRadius, mPaint); //画进度层圆角矩形(盖在背景层之上)
}
public void setProgress(int currentCount) {
this.progress = currentCount > maxProgress ? maxProgress : currentCount;
postInvalidate();
}
}
2、res/values/attrs.xml文件添加内容:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="verticalProgress">
<attr name="progress_radius" format="dimension" />
<attr name="progress_solid_color" format="color" />
<attr name="progress_end_color" format="color" />
<attr name="progress_border_width" format="dimension" />
</declare-styleable>
</resources>
3、res/values/colors.xml文件添加内容:
<color name="progress_bg">#FF4B85A1</color>
<color name="progress_fg">#FFA5DBE8</color>
4、xml布局文件使用:(根布局是RelativeLayout)
<包名.VerticalProgress
android:id="@+id/progress_bar"
android:layout_width="18dp"
android:layout_height="180dp"
android:layout_alignParentEnd="true"
android:layout_marginEnd="12dp"
android:layout_marginTop="93dp" />
5、代码中使用:
(1)初始化:findViewById(R.id.progress_bar)
(2)调用方法改变进度:setProgress(60)
综上,实现需求!
最后,悄悄告诉你一个小秘密,这个自定义组件还支持从下往上竖直显示进度哦。。。