Android开发--自定义时频域折线绘制图

2024-01-24

直接上干货!!!

1.XML

            <com.afison.newfault.view.CustomView
            android:id="@+id/customView"
            android:layout_width="match_parent"
            android:layout_height="200dp" />
            <Button
                android:id="@+id/generateButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_centerHorizontal="true"
                android:text="Generate Data"
                android:onClick="generateData"/>

2.测试函数

    public void generateData(View view) {
        // 生成随机数据
        float timeDomainData = (float) Math.random();
        float frequencyDomainData = (float) Math.random();

        // 更新视图
        customView.setTimeDomainData(timeDomainData);
        customView.setFrequencyDomainData(frequencyDomainData);
    }

3.CustomView实现

public class CustomView extends View {
    private Paint timeDomainPaint;
    private Paint frequencyDomainPaint;
    private Paint axisPaint; // 坐标轴画笔
    private Paint textPaint; // 文本画笔
    private LinkedList<Float> timeDomainDataList;
    private LinkedList<Float> frequencyDomainDataList;
    private int maxDataCount;
    private float minValue;
    private float maxValue;

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        timeDomainPaint = new Paint();
        timeDomainPaint.setColor(Color.BLUE);
        timeDomainPaint.setStrokeWidth(2f);
        timeDomainPaint.setAntiAlias(true);

        frequencyDomainPaint = new Paint();
        frequencyDomainPaint.setColor(Color.RED);
        frequencyDomainPaint.setStrokeWidth(2f);
        frequencyDomainPaint.setAntiAlias(true);

        axisPaint = new Paint();
        axisPaint.setColor(Color.WHITE);
        axisPaint.setStrokeWidth(2f);
        axisPaint.setAntiAlias(true);

        textPaint = new Paint();
        textPaint.setColor(Color.WHITE);
        textPaint.setTextSize(24f);
        textPaint.setAntiAlias(true);

        maxDataCount = 100;
        timeDomainDataList = new LinkedList<>();
        frequencyDomainDataList = new LinkedList<>();
    }

    public void setTimeDomainData(float data) {
        if (timeDomainDataList.size() >= maxDataCount) {
            timeDomainDataList.removeFirst();
        }
        timeDomainDataList.addLast(data);
        updateMinMaxValue();
        invalidate();
    }

    public void setFrequencyDomainData(float data) {
        if (frequencyDomainDataList.size() >= maxDataCount) {
            frequencyDomainDataList.removeFirst();
        }
        frequencyDomainDataList.addLast(data);
        updateMinMaxValue();
        invalidate();
    }

    private void updateMinMaxValue() {
        minValue = Float.MAX_VALUE;
        maxValue = -Float.MAX_VALUE;
        for (float value : timeDomainDataList) {
            minValue = Math.min(minValue, value);
            maxValue = Math.max(maxValue, value);
        }
        for (float value : frequencyDomainDataList) {
            minValue = Math.min(minValue, value);
            maxValue = Math.max(maxValue, value);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int width = getWidth();
        int height = getHeight();
        int halfHeight = height / 2;
        int dataSize = Math.min(timeDomainDataList.size(), frequencyDomainDataList.size());

        // 绘制坐标轴
        canvas.drawLine(0, halfHeight, width, halfHeight, axisPaint); // x 轴
        canvas.drawLine(0, 0, 0, height, axisPaint); // y 轴

        // 绘制坐标轴标注
        canvas.drawText(String.format(Locale.getDefault(), "%.2f", maxValue), 4, 24, textPaint); // 最大值
        canvas.drawText(String.format(Locale.getDefault(), "%.2f", minValue), 4, height - 4, textPaint); // 最小值
        canvas.drawText("时域", width - 200, halfHeight - 12, textPaint); // x 轴标注
        canvas.drawText("频域", width - 200, halfHeight + 24, textPaint); // y 轴标注

        // 绘制时域波形
        for (int i = 0; i < dataSize - 1; i++) {
            float x1 = (float) i * width / dataSize;
            float y1 = halfHeight - (timeDomainDataList.get(i) - minValue) / (maxValue - minValue) * halfHeight;
            float x2 = (float) (i + 1) * width / dataSize;
            float y2 = halfHeight - (timeDomainDataList.get(i + 1) - minValue) / (maxValue - minValue) * halfHeight;
            canvas.drawLine(x1, y1, x2, y2, timeDomainPaint);
        }

        // 绘制频域波形
        for (int i = 0; i < dataSize - 1; i++) {
            float x1 = (float) i * width / dataSize;
            float y1 = height - (frequencyDomainDataList.get(i) - minValue) / (maxValue - minValue) * height;
            float x2 = (float) (i + 1) * width / dataSize;
            float y2 = height - (frequencyDomainDataList.get(i + 1) - minValue) / (maxValue - minValue) * height;
            canvas.drawLine(x1, y1, x2, y2, frequencyDomainPaint);
        }
    }
}

4.效果展示

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android开发--自定义时频域折线绘制图 的相关文章

随机推荐

  • 鸿蒙自定义Http网络访问组件

    前言 DevEco Studio版本 4 0 0 600 使用效果 如何使用 参考文档 OpenHarmony http数据请求 1 module创建 File gt New gt Module 选择Static Library 2 相关类
  • 带你理解双路运算放大器LM258DR2G知识讲解

    LM258DR2G此双路运算放大器使用适用于四路运算放大器的电路设计 具有低漏功率 扩展至接地 VEE 的共模输入电压范围以及单电源或分离电源运行 此类器件与单电源应用中的标准运算放大器类型相比 具有若干不同的优点 它们可以在低至 3 0
  • 【产品兼容认证】WhaleStudio 成功兼容TiDB数据库软件

    平凯星辰和白鲸开源宣布成功完成产品兼容认证 北京 2023年12月27日 平凯星辰 北京 科技有限公司 以下简称平凯星辰 旗下的 TiDB 产品与白鲸开源的 WhaleStudio 已成功完成产品兼容性认证 这一重要合作旨在为全球客户提供更
  • 国产化率100%,北斗导航单日定位4500亿次,外媒:GPS将被淘汰

    追赶30年的技术差距 国产卫星导航系统 北斗 开始扬眉吐气 数据显示 北斗导航目前单日定位量达4500亿次 已经获得100多个国家的合作意向 甚至国际民航也摒弃以往 独宠 GPS的惯例 将北斗纳入参考标准 对此 有媒体直言 GPS多年来的技
  • ESM10A 消除对单独 PLC 的需求

    ESM10A 消除对单独 PLC 的需求 ESM10A 可以消除对单独 PLC 的需求 该程序是在 PC 上开发的 然后使用免费提供的简单易用的 EzSQ 软件下载到逆变器 似乎这些改进还不够 日立还在 SJ700 中添加了其他新功能 例如
  • 鸿蒙自定义Video播放器

    前言 DevEco Studio版本 4 0 0 600 使用效果 如何使用 参考文档 OpenHarmony Video使用说明 1 module创建 File gt New gt Module 选择Static Library 2 相关
  • Android开发--实现时间戳的动态刷新

    1 使用线程动态刷新 xml布局
  • 计算机Java项目|有机蔬菜商城

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板
  • 【安全】原型链污染 - Hackit2018

    目录 准备工作 解题 代码审计 Payload 准备工作 将这道题所需依赖模块都安装好后 运行一下 然后可以试着访问一下 报错是因为里面没内容而已 不影响 准备工作就做好了 解题 代码审计 const express require exp
  • 【C#】基础巩固

    最近写代码的时候各种灵感勃发 有了灵感 就该实现了 可是 实现起来有些不流畅 总是有这样 那样的卡壳 总结下来发现了几个问题 1 C 基础内容不是特别牢靠 理解的不到位 导致自己想出来了一些内容 但是无法使用正确的C 代码实现 导致灵感无法
  • 手把手教你使用HarmonyOS本地模拟器

    我们通过下面的动图来回顾下手机本地模拟器的使用效果 本期 我们将为大家介绍HarmonyOS本地模拟器的版本演进 并手把手教大家使用HarmonyOS本地模拟器 一 本地模拟器的版本演进 2021年12月31日 经过一个版本的迭代优化 随D
  • 【UE】在控件蓝图中通过时间轴控制材质参数变化

    效果 步骤 1 新建一个控件蓝图和一个材质 2 打开材质 设置材质域为用户界面 混合模式设置为 半透明 在材质图表中添加两个参数来控制材质的颜色和不透明度 3 对材质创建材质实例 4 打开控件蓝图 在画布面板中添加一个图像控件 将刚才创建的
  • 案例研究:YGG 如何通过 GAP 帮助 Pixels 扩大玩家群体

    在 Sky Mavis 联合创始人 Jeffrey Jihoz Zirlin 在 YGG Web3 游戏峰会 W3GS 上发表主题演讲时 他向在场的人们透露 MMO 农场游戏 Pixels 的日活跃用户数已经超过了 130 000 人 这使
  • logback配置xml日志文件(保姆级教程)

    前言 这是个啥 这就是个控制日志输出格式 控制日志输出位置 控制日志输出环境 控制日志输出级别的玩意 控制忽略输出的日志就这些功能 没有什么很复杂的东西 废话不说多了 配置介绍 configuration
  • 题解 | #二维数组中的查找#C++二维数组暴力解法

    试用期被裁概率大嘛 华为西安 三一 在电信工作可以躺平吗 选offer 2022届offer收割机手把手教你拿offer 面试篇 新媒体运营面试的常问题都整理出来啦 还是准备辞职了 感觉我真的不适合上班 攒了点钱 准备辞职了 后面也不打算再
  • 高防服务器什么意思

    高防服务器什么意思 为什么要用高防服务器 小编为您整理发布高防服务器什么意思的解读 高防服务器是指具备较高防御能力的服务器 能够抵御DDoS CC等网络攻击 高防服务器通常用于保护游戏 APP 金融 电商等业务 这些领域因为其业务特性 容易
  • 2024最强Java面试八股文合集(持续更新)

    今天要谈的主题是关于求职 求职是在每个技术人员的生涯中都要经历多次 对于我们大部分人而言 在进入自己心仪的公司之前少不了准备工作 有一份全面细致 面试题 将帮助我们减少许多麻烦 在跳槽季来临之前 特地做这个系列的文章 一方面帮助自己巩固下基
  • DSCA190V 57310001-PK

    DSCA190V 57310001 PK DSCA190V 57310001 PK 具有两个可编程继电器功能 并安装在坚固的 XP 外壳中 DSCA190V 57310001 PK 即可使用 只需最少的最终用户校准 DSCA190V 573
  • 深度学习(5)--Keras实战

    一 Keras基础概念 Keras是深度学习中的一个神经网络框架 是一个高级神经网络API 用Python编写 可以在TensorFlow CNTK或Theano之上运行 Keras优点 1 允许简单快速的原型设计 用户友好性 模块化和可扩
  • Android开发--自定义时频域折线绘制图

    直接上干货 1 XML