Android自定义圆环进度条/刻度仪表盘(单环单点带动画)

news2024/11/26 20:35:06

效果图:

 

1.自定义HeartDashBoardView

/**
 * 刻度仪表盘
 */
public class HeartDashBoardView extends View {
    private static final float START_ANGLE = 135f;
    private static final float MAX_ANGLE = 270f;
    private float progress = 0;
    private float centerX;
    private float centerY;
    private float width;
    private float height;
    private int lineWidth = dp2px(8); // 绘制圆环的线宽
    private int pointWidth = dp2px(2); // 绘制圆点线宽

    private SweepGradient sweepGradient;

    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Paint pointPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private ObjectAnimator animator;

    private int[] colors = {
            Color.parseColor("#09F5E6"),
            Color.parseColor("#09F5E6"),//浅色
            Color.parseColor("#23F2A4"),
            Color.parseColor("#40EF59"),
            Color.parseColor("#7EED26"),
            Color.parseColor("#B7EC15"),
            Color.parseColor("#FFE300"),
            Color.parseColor("#FF0B00"),
            Color.parseColor("#FF0000"),//深色
    };

    public HeartDashBoardView(Context context) {
        this(context, null);
    }

    public HeartDashBoardView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public HeartDashBoardView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        paint.setColor(Color.GRAY);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeWidth(lineWidth);

        pointPaint.setColor(Color.WHITE);
        pointPaint.setStyle(Paint.Style.STROKE);
        pointPaint.setStrokeWidth(pointWidth);
    }

    private void setProgress(float progress) {
        this.progress = progress;
        invalidate();
    }

    public void setHeartProgress(float progress) {
        animator = ObjectAnimator.ofFloat(this, "progress", 0, progress);
        animator.setDuration(2000);
        animator.setInterpolator(new FastOutSlowInInterpolator());
        animator.start();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = getWidth();
        height = getHeight();
        centerX = getWidth() / 2;
        centerY = getHeight() / 2;
        sweepGradient = new SweepGradient(centerX, centerY, colors, null);
        //改变开始渐变的角度(默认从右边开始画圆渐变,旋转90度就从下方开始画圆渐变,旋转之后更好设置颜色渐变值)
        Matrix matrix = new Matrix();
        matrix.setRotate(90, centerX, centerY);
        sweepGradient.setLocalMatrix(matrix);
        paint.setShader(sweepGradient);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 绘制环形
        drawArc(canvas);
        // 绘制末尾圆点
        drawPoint(canvas);
    }

    private void drawArc(Canvas canvas) {
        int padding = lineWidth + pointWidth;
        canvas.drawArc(padding, padding, width - padding, height - padding, START_ANGLE, MAX_ANGLE, false, paint);
    }

    private void drawPoint(Canvas canvas) {
        Path path = new Path();
        float sweepAngle = MAX_ANGLE * progress / 100;
        int padding = lineWidth + pointWidth;
        path.addArc(padding, padding, width - padding, height - padding, START_ANGLE, sweepAngle);
        PathMeasure measure = new PathMeasure(path, false);
        float[] pos = new float[2];
        measure.getPosTan(measure.getLength() - 1, pos, null);
        pointPaint.setColor(Color.parseColor("#FF7968"));
        pointPaint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(pos[0], pos[1], lineWidth - pointWidth, pointPaint);

        pointPaint.setColor(Color.WHITE);
        pointPaint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(pos[0], pos[1], lineWidth - pointWidth, pointPaint);
    }

    public int dp2px(final float dpValue) {
        final float scale = Resources.getSystem().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

2.布局中使用

            <com.hwd.flowfit.ui.widget.HeartDashBoardView
                android:id="@+id/heartChart"
                android:layout_width="130dp"
                android:layout_height="130dp"
                android:layout_marginStart="30dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

3.设置进度

heartChart.setHeartProgress(30F)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/753503.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

快快快快快快快快快快排

作者简介&#xff1a;დ旧言~&#xff0c;目前大一&#xff0c;现在学习Java&#xff0c;c&#xff0c;Python等 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 望小伙伴们点赞&#x1f44d;收藏✨加关注哟&#x1f495;&#x1f495; C语言实现快排☺️ ℹ️…

应届毕业生要如何准备秋招简历?

秋招对于应届毕业生是一个求职的重要渠道&#xff0c;但是很多应届毕业生却不知道要如何制作秋招简历。那么&#xff0c;秋招简历应该如何制作呢&#xff1f;接下来&#xff0c;小编给大家讲一讲简历制作&#xff08;https://www.jiaobu365.com/&#xff09;的哪些事&#xff0…

2023 世界人工智能大会(WAIC)人才培养论坛成功举办!

Datawhale论坛 来源&#xff1a;2023 世界人工智能大会&#xff08;WAIC&#xff09; 前 言 2023 年 7 月 8 日&#xff0c;“2023世界人工智能大会”&#xff08;WAIC&#xff09;落下帷幕。7 月 8 日上午&#xff0c;WAIC 的主要分论坛之一“AIGC时代下的青年开发者人才培养…

什么样的性能测试工具才算是好的工具呢?

一、性能测试工具的特征 调度能力 因为性能测试不可能由一台压力机完成或者说大部分情况下&#xff0c;我们不能不可能由一台压力机来完成&#xff0c;凡是对压力真正有所要求的场景&#xff0c;往往是多台压力机共同施加压力完成性能测试&#xff1b;因此&#xff0c;性能测…

【GitHub】强大的终端录制工具-Terminalizer

Terminalizer 是一个GitHub上优秀的开源项目&#xff0c;目前项目点赞数已达&#xff1a;14k&#xff0c;该项目可以轻松记录下你在命令行的操作&#xff0c;并将录制好的内容输出成 gif 图像或直接分享到网上。 项目开源协议&#xff1a;MIT 项目主开发语言&#xff1a;JavaSc…

Vue计算属性:简化数据处理和视图更新的利器

一、计算属性的基本使用 计算属性&#xff1a;一个特殊属性&#xff0c;值依赖于另外一些数据动态计算出来。&#x1f6a9;&#x1f6a9;&#x1f6a9;计算属性特点&#xff1a;函数内使用的变量改变&#xff0c;重新计算结果返回。&#x1f4a3;&#x1f4a3;&#x1f4a3;注…

uniapp实现聊天消息触,vue3和vue2实现聊天消息触底 scrollTop ,scrollHeight Pc端H5端都适用

uniapp触底SDN链接如下(本人的另一篇博客) uniapp聊天时时触底链接 Pc端 模拟手机端H5 vue3写法 <template><div><!-- 聊天窗体 --><div class"test" id"gundong"><div class"text" v-for"p in chat"&…

Html基础知识学习——兼容问题与解决方法

文章目录 1.计算一定要精确&#xff0c;不要让内容的宽高超出我们设置的宽高&#xff0c;在IE6下内容会撑开设置好的宽高2.元素浮动&#xff0c;宽度需要内容撑开&#xff0c;就给里面的块元素都加浮动3.在ie6.ie7下元素要浮动并在同一行 就给这些元素都加浮动4.注意标签嵌套规…

C# WPF实现动画渐入暗黑明亮主题切换效果

C# WPF实现动画渐入暗黑明亮主题切换效果 效果图如下最近在Bilibili的桌面端看到一个黑白主题切换的效果感觉,挺有意思。于是我使用WPF尝试实现该效果。 主要的切换效果,基本实现不过还存在一些小瑕疵,比如字体等笔刷不能跟随动画进入进行切换。因为Bilibili的客户端是用el…

【算法 -- LeetCode】(018) 四数之和

1、题目 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#xff1a; …

【Hadoop 01】简介

1 Hadoop 简介 Hadoop适合海量数据分布式存储和分布式计算 Hadoop 3.x的细节优化&#xff1a; Java改为支持8及以上HDFS支持纠删码HDFS支持多NameNodeMR任务级本地优化多重服务默认端口变更 Hadoop主要包含三大组件&#xff1a;HDFSMapReduceYARN HDFS负责海量数据的分布式存…

HttpRunner自动化之跨文件传递变量值输出变量值

跨文件传递&输出变量值 output: 输出变量值,此参数在httprunner2.2版本的时候被 export 代替&#xff0c;跨文件传递参数的功能在httprunner2.2之后不生效。&#xff08;但是实际测试过程中&#xff0c;还可以使用跨文件功能&#xff09; export: 输出变量值,且可以跨文件…

(黑客)网络安全靠自学?你不要命啦?

引言⚡ ✈️网络安全&#xff0c;顾名思义&#xff0c;无安全&#xff0c;不网络。现如今&#xff0c;安全行业飞速发展&#xff0c;我们呼吁专业化的 就职人员 与 大学生 &#xff0c;而你&#xff0c;认为自己有资格当黑客吗&#xff1f; ✒️本文面向所有信息安全领域的初学…

2023-07-14:讲一讲Kafka与RocketMQ中存储设计的异同?

2023-07-14&#xff1a;讲一讲Kafka与RocketMQ中存储设计的异同&#xff1f; 答案2023-07-14&#xff1a; 在Kafka中&#xff0c;文件的布局采用了Topic/Partition的方式&#xff0c;每个分区对应一个物理文件夹&#xff0c;且在分区文件级别上实现了顺序写入。然而&#xff0…

springboot逍遥大药房管理系统

逍遥大药房管理系统的需求和管理上的不断提升&#xff0c;逍遥大药房管理的潜力将无限扩大&#xff0c;逍遥大药房管理系统在现代社会上被广泛关注&#xff0c;本系统对此进行总体分析&#xff0c;将逍遥大药房信息管理的发展提供参考。逍遥大药房管理系统对逍遥大药房管理方面…

xxl-job的简单使用

xxl-job是一个分布式任务调度框架&#xff0c;在Spring中&#xff0c;提供有任务调度的注解功能&#xff0c;在之前的项目中&#xff0c;非分布式任务都可以直接使用Spring框架提供的Scheduled注解和EnableScheduling注解来实现定时任务。 EnableScheduling注解加载项目启动类上…

Azure Kinect DK 在设备管理器找不到此设备

参考 Azure Kinect DK 在设备管理器找不到此设备_Thomas_yx的博客-CSDN博客 type-c------------------type-c 接电脑&#xff0c;数据传输 圆------------------usb 电脑线

RabbitMQ ---- 交换机

RabbitMQ ---- 交换机 1. Exchanges1.1 Exchanges 概念1.2 Exchanges 的类型1.3 无名 exchange 2. 临时队列3. 绑定&#xff08;bindings&#xff09;4. Fanout4.1 Fanout 介绍4.2 Fanout 实战 5. Direct exchange5.1 回顾5.2 Direct exchange 介绍5.3 多重绑定5.4 实战 6. Top…