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

2024-01-24 13:44

本文主要是介绍Android开发--自定义时频域折线绘制图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

直接上干货!!!

1.XML

            <com.afison.newfault.view.CustomViewandroid:id="@+id/customView"android:layout_width="match_parent"android:layout_height="200dp" /><Buttonandroid: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);}}@Overrideprotected 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.效果展示

这篇关于Android开发--自定义时频域折线绘制图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/639883

相关文章

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

PyQt5 GUI 开发的基础知识

《PyQt5GUI开发的基础知识》Qt是一个跨平台的C++图形用户界面开发框架,支持GUI和非GUI程序开发,本文介绍了使用PyQt5进行界面开发的基础知识,包括创建简单窗口、常用控件、窗口属性设... 目录简介第一个PyQt程序最常用的三个功能模块控件QPushButton(按钮)控件QLable(纯文本

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码