自定义View之VerticalProgress

根据公司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)

综上,实现需求!

最后,悄悄告诉你一个小秘密,这个自定义组件还支持从下往上竖直显示进度哦。。。

猜你喜欢

转载自blog.csdn.net/Agg_bin/article/details/84965093