自定义ProgressBar-油表,汽车速度表控件

本文介绍了如何在Android中自定义一个漂亮的ProgressBar,形如汽车的油表或速度表。通过分析需求,使用ValueAnimator平滑过渡数值变化,详细讲解了画圆弧、刻度、指针以及指针动画的实现步骤。提供了布局文件的简单实现,并鼓励读者尝试开发更多控件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、写在前面的话

今天做了个控件,觉得还挺漂亮,就拿出来给大家分享一下,主要为了给大家介绍一下ValueAnimator这个动画,确实也没啥好说的,网上一堆教程,还是说说说画这个动画好了。

二、需求分析

刚拿到需求,我们分析一下。控件有两道圆弧,第一道上面有数据段,第二段是具体数值的指示段。

数值变换的时候,需要平滑过渡,不能突兀。

三、开始画。

1、画圆弧

  private void drawArc(Canvas canvas) {
        mBgPaint.setStrokeWidth(mProgressSize);
        canvas.drawArc(mProgressSize * lineSize, mProgressSize * lineSize, mWidth - mProgressSize * lineSize, mHeight - mProgressSize * lineSize, 150, 240, false, mBgPaint);
        //画推荐度数
        canvas.drawArc(mProgressSize * lineSize, mProgressSize * lineSize, mWidth - mProgressSize * lineSize, mHeight - mProgressSize * lineSize, 150 + lowProgress * 240 / 100, (highProgress - lowProgress) * 240 / 100, false, mProgressPaint);
        //画推荐度数的值
        int r = mWidth / 2 - mProgressSize;
        int x = getArcX(150 + lowProgress * 240 / 100, r);
        int y = getArcY(150 + lowProgress * 240 / 100, r);
        int x2 = getArcX(150 + highProgress * 240 / 100, r);
        int y2 = getArcY(150 + highProgress * 240 / 100, r);
        if (x < mWidth / 2) {
            x = x - 13;
        } else {
            y = y + 7;
            x = x - 3;

        }
        if (x2 < mWidth / 2) {
            x2 = x2 - 13;
        } else {
            x2 = x2 - 3;

            y2 = y2 + 7;

        }
        canvas.drawText(stringLowProgress, x, y, mTextPaint);
        canvas.drawText(stringHighProgress, x2, y2, mTextPaint);

        mBgPaint.setStrokeWidth(mProgressSize / 3);
        canvas.drawArc(mProgressSize * offset, mProgressSize * offset, mWidth - mProgressSize * offset, mHeight - mProgressSize * offset, 150, 240, false, mBgPaint);
    }

为什么会/100呢,因为这里我把进度放大了一百倍,为了值的变化更流畅。

2、画刻度

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void drawLine(Canvas canvas) {
        canvas.drawArc(mProgressSize * lineSize, mProgressSize * lineSize, mWidth - mProgressSize * lineSize, mHeight - mProgressSize * lineSize, 150 + 6 - 1, 2, false, mWhitePaint);
        for (int i = 1; i < 10; i++) {
            canvas.drawArc(mProgressSize * lineSize, mProgressSize * lineSize, mWidth - mProgressSize * lineSize, mHeight - mProgressSize * lineSize, 150 + 24 * i - 1, 2, false, mWhitePaint);
        }
        canvas.drawArc(mProgressSize * lineSize, mProgressSize * lineSize, mWidth - mProgressSize * lineSize, mHeight - mProgressSize * lineSize, 30 - 6 - 1, 2, false, mWhitePaint);
    }

这里的刻度我们画一小段白色的圆弧,大家可以根据自己的要求改一下。

3、画指针


    private void drawProgress(Canvas canvas) {
        //计算当前的角度
        int angle = 150 + mProgress * 240 / mMaxProgress;
        int r = mWidth / 2 - mProgressSize * offset;
        int cx = getArcX(angle, r);
        int cy = getArcY(angle, r);
        canvas.drawCircle(cx, cy, 4, mProgressPaint);

        //圆外一点的坐标
        int x = getArcX(angle, r + 35);
        int y = getArcY(angle, r + 35);

        //控制点1
        int co1x = getArcX(angle - 4, r + 5);
        int co1y = getArcY(angle - 4, r + 5);
        //控制点2
        int co2x = getArcX(angle + 4, r + 5);
        int co2y = getArcY(angle + 4, r + 5);
        path.reset();
        path.moveTo(co1x, co1y);
        path.lineTo(co2x, co2y);
        path.lineTo(x, y);
        path.lineTo(co1x, co1y);
        canvas.drawPath(path, mSmallWhitePaint);
        canvas.drawCircle(cx, cy, 1, mWhitePaint);


    }

4、指针动画

    //    /**
//     * 进度显示动画效果初始化
//     */
    private void initValueAnimator() {
        valueAnimator = new ValueAnimator();
        valueAnimator.setInterpolator(interpolator);
        valueAnimator.addUpdateListener(new ValueAnimatorListenerImp());
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值