自定义View之Android波浪效果的进度条

老规矩,先来一波效果图这里写图片描述
再来看看具体实现

首先肯定要先画一个背景
我是通过判断值的大小来改变背景的颜色

   private void drawBgCircle(Canvas canvas) {
        if (progress <= 25 && progress >= 0) {
            mPaintInnerCircle.setColor(Color.parseColor("#55EA4602"));
        } else if (progress > 25 && progress <= 50) {
            mPaintInnerCircle.setColor(Color.parseColor("#55F48600"));
        } else if (progress > 50 && progress <= 75) {
            mPaintInnerCircle.setColor(Color.parseColor("#55A8D309"));
        } else {
            mPaintInnerCircle.setColor(Color.parseColor("#5548B619"));
        }
        canvas.drawCircle(mCenterXY, mCenterXY, mRadius, mPaintInnerCircle);
    }

然后再画外边缘的线


    /**
     * 实现画刻度线的功能
     */
    private void drawLine(final Canvas canvas) {
        // 保存之前的画布状态
        canvas.save();
        // 移动画布,实际上是改变坐标系的位置
        canvas.translate(mCenterXY, mCenterXY);
//        canvas.rotate(30);
        // 设置画笔的宽度(线的粗细)
        linePaint.setStrokeWidth(UIUtils.sp2px(1));
        // 累计叠加的角度
        float c = 0;
        float a = sweepAngle / 100;
        for (int i = 0; i <= 100; i++) {
            if (c <= sweepAngle) {// 如果累计画过的角度,小于当前有效刻度
                if (i == 0 || i == 100) {
                    double p = c / (double) sweepAngle;
                    int red = 255 - (int) (p * 255);
                    int green = (int) (p * 255);
                    linePaint.setARGB(255, red, green, 50);
                    canvas.drawLine(0, mRadius + 20, 0, mRadius + 60, linePaint);
                } else {
                    double p = c / (double) sweepAngle;
                    int red = 255 - (int) (p * 255);
                    int green = (int) (p * 255);
                    linePaint.setARGB(255, red, green, 50);
                    canvas.drawLine(0, mRadius + 20, 0, mRadius + 50, linePaint);
                }

                // 画过的角度进行叠加
                c += a;
            } else {
                linePaint.setColor(Color.GREEN);
                canvas.drawLine(0, mRadius + 20, 0, mRadius + 60, linePaint);
            }
            canvas.rotate(a);
        }
        // 恢复画布状态。
        canvas.restore();
    }

然后画文字

 private void drawText(Canvas canvas) {
        //绘制中心的文字
        String text = progress + "%";
        mPaintText.getTextBounds(text, 0, text.length(), mRectProgress);
        canvas.drawText(text, (getWidth() - mRectProgress.width()) / 2, (getHeight() + mRectProgress.height()) / 2, mPaintText);
        //绘制tips的文字
        canvas.drawText(mTipString, (getWidth() - mRectTips.width()) / 2, (getHeight() / 2 + mRectProgress.height()) / 2, mPaintTextTips);
    }

最后看来看看如何画波浪
首先通过path来创建波浪的线条(这段代码是复制的,难点就在这里)

 /**
     * 创建波浪,主要是通过path来创建
     */
    private void createWavePath(int progress) {
        mPath.reset();
        float absY;
        float sweepAngle;
        float startAngle;
        float absX;
        if (progress >= 50) {
            absY = mRadius * 2 * (progress * 1.0f / 100);
            float angle = (float) (Math.asin((absY - mRadius) * 1.0f / mRadius) * 180 / Math.PI);
            absX = (float) (mRadius * Math.cos(angle * Math.PI / 180));
            sweepAngle = angle * 2 + 180;
            startAngle = -angle;
        } else {
            absY = mRadius * 2 * (progress * 1.0f / 100);
            float angle = (float) (Math.acos((mRadius - absY) * 1.0f / mRadius) * 180 / Math.PI);
            absX = (float) (mRadius * Math.sin(angle * Math.PI / 180));
            sweepAngle = angle * 2;
            startAngle = 90 - angle;
        }

        int startX = (int) (mRadius - absX) + mStrokeWidth;

        float x, y;
        for (int i = 0; i < absX * 2; i++) {
            x = i + startX;
            y = (float) (mWaveHeight * Math.sin((i * 1.5f + mOffsetX) / mRadius * Math.PI)) + (mRadius * 2 - absY) + mStrokeWidth;
            if (i == 0) {
                mPath.moveTo(x, y);
            } else {
                mPath.quadTo(x, y, x + 1, y);
            }
        }
        RectF rectF = new RectF(mStrokeWidth, mStrokeWidth, mRadius * 2 + mStrokeWidth, mRadius * 2 + mStrokeWidth);
        mPath.arcTo(rectF, startAngle, sweepAngle);
        mPath.close();
    }

然后开始绘制

private void drawnWaveSetPaint(Canvas canvas) {
        if (progress <= 25 && progress >= 0) {
            mPaintWater.setColor(Color.parseColor("#EA4602"));
        } else if (progress > 25 && progress <= 50) {
            mPaintWater.setColor(Color.parseColor("#F48600"));
        } else if (progress > 50 && progress <= 75) {
            mPaintWater.setColor(Color.parseColor("#A8D309"));
        } else {
            mPaintWater.setColor(Color.parseColor("#48B619"));
        }
        canvas.drawPath(mPath, mPaintWater);
    }

最后提供两个开启动画和关闭动画的方法

 /**
     * 设置进度
     */
    public void setProgress(int progress) {
        if (progress < 0) {
            this.progress = 0;
        } else {
            this.progress = progress;
        }
        invalidate();
    }

    /**
     * 开始动画
     */
    public void startWave() {
        if (!isWaving && mHandler != null) {
            mHandler.sendEmptyMessage(10);
        }
        isWaving = true;
    }

    /**
     * 关闭动画
     */
    public void stopWave() {
        if (mHandler != null) {
            mHandler.removeMessages(10);
        }
        isWaving = false;
    }

创建handler

  private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            mOffsetX = mOffsetX + 8;
            if (mOffsetX > 10000) {
                mOffsetX = 0;
            }
            invalidate();
        }
    };

这里写图片描述
搞定!!!!!!!!!!!!!!!!!!!!!!1

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值