精通Android自定义View(十四)绘制水平向右加载的进度条

1引言

1 精通Android自定义View(一)View的绘制流程简述
2 精通Android自定义View(二)View绘制三部曲
3 精通Android自定义View(三)View绘制三部曲综合简述
4 精通Android自定义View(四)自定义属性使用详解
5 精通Android自定义View(五)自定义属性值使用详情


6 精通Android自定义View(六)绘制篇Paint分析
7 精通Android自定义View(七)绘制篇Canvas分析
8 精通Android自定义View(八)绘制篇Canvas分析绘制文字
9 精通Android自定义View(九)绘制篇Canvas分析绘制图片
10 精通Android自定义View(十)绘制篇Canvas分析之绘制Path
11 精通Android自定义View(十一)绘制篇Canvas分析之裁剪


12 精通Android自定义View(十二)绘制圆形进度条
13 精通Android自定义View(十三)事件分发简述

 

2 效果图

 

3 源码


public class HorizontalProgressBar extends ProgressBar {


    //定义一个画笔
    protected Paint mPaint = new Paint();
    //设置默认的显示进度文字的颜色
    protected int mTextColor = 0xff253688;
    //设置显示默认的显示进度的文字的大小
    protected int mTextSize = dp2px(10);
    //设置默认的绘制进度条的高度
    protected int mProgressBarHeight = dp2px(10);

    //设置默认的绘制进度条颜色
    protected int mBarColor = 0xffffcc00;
    //未加载进度条的颜色
    protected int mUnBarColor = 0xffe6e6e6;
    //绘制进度条的实际宽度
    private int mMeasureHeight;
    private int mMeasureWidth;
    //默认view的宽度
    private int mDefaultWidth = dp2px(100);
    private int mDefaultHeight = dp2px(10);
    private boolean isBackgroundDraw = false;

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

    public HorizontalProgressBar(Context context, AttributeSet attrs,
                                 int defStyle) {
        super(context, attrs, defStyle);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setTextSize(mTextSize);
        mPaint.setColor(mTextColor);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //测量计算宽度
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        if (widthSpecMode == MeasureSpec.EXACTLY) {
            //当specMode = EXACTLY时,精确值模式,即当我们在布局文件中为View指定了具体的大小
            mMeasureWidth = widthSpecSize;
        } else {
            //指定默认大小
            mMeasureWidth = mDefaultWidth;
            if (widthSpecMode == MeasureSpec.AT_MOST) {
                mMeasureWidth = Math.min(mMeasureWidth, widthSpecSize);
            }
        }

        //测量计算View的高
        int heightSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        if (heightSpecMode == MeasureSpec.EXACTLY) {
            //当specMode = EXACTLY时,精确值模式,即当我们在布局文件中为View指定了具体的大小
            mMeasureHeight = heightSpecSize;
        } else {
            //指定默认大小
            mMeasureHeight = mDefaultHeight;
            if (heightSpecMode == MeasureSpec.AT_MOST) {
                mMeasureHeight = Math.min(mMeasureHeight, heightSpecSize);
            }
        }
        //重新测量
        setMeasuredDimension(mMeasureWidth, mMeasureHeight);
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {

        canvas.save();
        //绘制未加载的进度
        //float start = progressPosTextX + textWidth;
        float start = 0;
        mPaint.setColor(mUnBarColor);
        mPaint.setStrokeWidth(mProgressBarHeight*2);
        canvas.drawLine(start, 0, mMeasureWidth, 0, mPaint);


        //定义画笔的初始位置
        canvas.translate(getPaddingLeft(), getHeight() / 2);
        //计算加载进度的比例
        float radio = getProgress() * 1.0f / getMax();
        // 计算已加载的进度
        float progressPosTextX = (int) (mMeasureWidth * radio);
        //定义进度上显示的文字信息
        String text = getProgress() + "%";
        //获取绘制文字的宽与高
        float textWidth = mPaint.measureText(text);
        float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;

        
        //判断绘制
        float progressPosX=progressPosTextX;
        if (progressPosTextX + textWidth > mMeasureWidth) {
            progressPosTextX = mMeasureWidth - textWidth;
        }


        //绘制已加载的进度
        mPaint.setColor(mBarColor);
        mPaint.setStrokeWidth(mProgressBarHeight);
        canvas.drawLine(0, 0, progressPosX, 0, mPaint);

        //绘制加载显示的进度文字
        mPaint.setColor(mTextColor);
        canvas.drawText(text, progressPosTextX, -textHeight, mPaint);


        canvas.restore();

    }


    //将设置的db转为屏幕像素
    protected int dp2px(int dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, getResources().getDisplayMetrics());
    }
}

 

早起的年轻人 CSDN认证博客专家 移动开发 项目管理 Java
只要用心去做,每一件事情还是有可能成功的,当然成功是没有界限的,只不过是达到自己心里的那个目标,公众号:我的大前端生涯,一个爱喝茶的程序员,通常会搞搞SpringBoot 、Herbinate、Mybatiys、Android、iOS、Flutter、Vue、小程序等.
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页