当前位置: 首页 > news >正文

Android 简单快速实现 下弧形刻度尺(滑动事件)

效果图:

直接上代码:

package com.my.view;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;import androidx.annotation.Nullable;/*** 弧形可滑动刻度控件*/
public class ArcRulerView extends View {//弧形开始的角度private float startAngle = 180f;//弧面所跨的弧度private final float sweepAngle = 180f;//outer总刻度private final int outerTotalDial = 80;//inner总刻度private final int innerTotalDial = (int) (outerTotalDial * 2.5f);//每次滑动角度private final float moveAnglePre = sweepAngle / outerTotalDial * 0.5f;//inner半圆的半径private int innerRadius;//outer半圆的半径private int outerRadius;private String TAG = ArcRulerView.class.getSimpleName();private int dp2px(int i) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, i, getResources().getDisplayMetrics());}//inner刻度线的宽度private int innerLineWidth = 1;//inner刻度线的高度private int innerLineHeight = dp2px(18);//刻度线的宽度private int outerLineWidth = dp2px(2);//outer刻度线的高度private int outerLineHeight = dp2px(36);private Bitmap mRulerPoint;private int sp2px(int i) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, i, getResources().getDisplayMetrics());}private Paint outerLinePaint, innerLinePaint, innerBgPaint, outerBgPaint;public ArcRulerView(Context context) {this(context, null);}public ArcRulerView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public ArcRulerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {this(context, attrs, defStyleAttr, 0);}public ArcRulerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);init();}private void init() {outerLinePaint = new Paint();outerLinePaint.setColor(Color.WHITE);outerLinePaint.setAntiAlias(true);innerLinePaint = new Paint();innerLinePaint.setColor(Color.parseColor("#D6D6D6"));innerLinePaint.setAntiAlias(true);outerBgPaint = new Paint();outerBgPaint.setColor(Color.parseColor("#1E1E1E"));outerBgPaint.setAlpha(30);outerBgPaint.setAntiAlias(true);innerBgPaint = new Paint();innerBgPaint.setColor(Color.parseColor("#D6D6D6"));innerBgPaint.setAlpha(40);innerBgPaint.setAntiAlias(true);mRulerPoint = BitmapFactory.decodeResource(getResources(), R.drawable.ic_ruler_point);}private float dx = 0, dy = 0, mx = 0, my = 0;private boolean mIsDrawDial = false;@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:dx = event.getX();dy = event.getY();break;case MotionEvent.ACTION_MOVE:if (!mIsDrawDial) {mx = event.getX();my = event.getY();float md = mx - dx;//x轴滑动距离if (md > 0 && startAngle < sweepAngle + 90) {if (md > 5) {startAngle += moveAnglePre;invalidate();dx = mx;dy = my;}} else if (md < 0 && startAngle > sweepAngle - 90) {if (Math.abs(md) > 5) {startAngle -= moveAnglePre;invalidate();dx = mx;dy = my;}}}break;case MotionEvent.ACTION_UP:break;}return true;}@Overridepublic void draw(Canvas canvas) {super.draw(canvas);outerRadius = (int) (getWidth() * 0.68f);//outer半径innerRadius = (int) (outerRadius - outerLineHeight - innerLineHeight * 0.8f);//inner半径if (!mIsDrawDial) {mIsDrawDial = true;//outer背景float outerBgRadius = Math.max(getHeight(), outerRadius);float outerWidthDiff = outerBgRadius - getWidth() * 0.5f;canvas.drawArc(-outerWidthDiff, 0, getWidth() + outerWidthDiff, outerBgRadius * 2, startAngle, sweepAngle, true, outerBgPaint);//inner背景float innerWidthDiff = innerRadius - getWidth() * 0.5f;canvas.drawArc(-innerWidthDiff, getHeight() - innerRadius, getWidth() + innerWidthDiff, innerRadius * 2f + getHeight() - innerRadius, startAngle, sweepAngle, true, innerBgPaint);drawDial(startAngle, sweepAngle, outerTotalDial, outerLineWidth, outerLineHeight, outerRadius, outerLinePaint, canvas);//outer刻度drawDial(startAngle, sweepAngle, innerTotalDial, innerLineWidth, innerLineHeight, innerRadius, innerLinePaint, canvas);//inner刻度mIsDrawDial = false;}canvas.drawBitmap(mRulerPoint, getWidth() * 0.5f - mRulerPoint.getWidth() * 0.5f, 0, null);//指针}/*** 画刻度盘*/private void drawDial(float startAngle, float sweepAngle, int dialCount, int lineWidth, int lineHeight, int radius, Paint paint, Canvas canvas) {paint.setStrokeWidth(lineWidth);float length;float angle;//根据需要显示的刻度总个数遍历for (int i = 0; i <= dialCount; i++) {//每一个刻度对应的起始角度为180度+(总度数/个数)*对应刻度的位置angle = ((sweepAngle) / (dialCount * 1f) * i) + startAngle;//线条的起始点位置float[] startP;//线条的end点的位置float[] endP;//短刻度条的长度为长刻度条的一半length = lineHeight;startP = getPointFromAngleAndRadius(angle, radius);endP = getPointFromAngleAndRadius(angle, radius - length);//高亮计算int alpha = 255;int centerAngle = 270;if (angle != centerAngle) {int angleDiff = (int) Math.abs(angle - centerAngle);int anglePer = 255 / 45;alpha = 255 - angleDiff * anglePer;}LibLogUtil.i(TAG, "alpha=" + alpha);alpha = Math.max(alpha, 0);paint.setAlpha(alpha);//画出对应的刻度条canvas.drawLine(startP[0], startP[1], endP[0], endP[1], paint);}}/*** 根据刻度条相应的角度算出点位置** @param angle* @param radius* @return*/private float[] getPointFromAngleAndRadius(float angle, float radius) {//根据三角函数公式可以知道,横坐标值为(刻度条+innnerradius)也就是刻度条对应圆的半径//乘以一个cos(angle),因为我们是以(getWidth() / 2,控件的高度)位置建的坐标系//而真正的坐标系的位置为控件左上角,所以算出的值后需要+getWidth() / 2或者getHeight()double x = radius * Math.cos(angle * Math.PI / 180) + getWidth() / 2;double y = radius * Math.sin(angle * Math.PI / 180) + getHeight();return new float[]{(float) x, (float) y};}}

相关文章:

Android 简单快速实现 下弧形刻度尺(滑动事件)

效果图&#xff1a; 直接上代码&#xff1a; package com.my.view;import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Pai…...

【Go】常见的变量与常量

变量 常见的变量声明方式 一、声明单个变量的多种方式 1.声明一个变量初始化一个值 //声明变量 默认值是0&#xff0c;var a int//初始化一个值a 1fmt.Println(a) 2. 在初始化的时候省去数据类型&#xff0c;通过值自动匹配当前的变量的数据类型 var b 2fmt.Println(&quo…...

Qt使用sqlite数据库及项目实战

一.sqlite使用介绍 在Qt中使用SQLite数据库非常简单&#xff0c;SQLite是一个轻量级的嵌入式数据库&#xff0c;不需要单独的数据库服务器&#xff0c;完全使用本地文件来存储数据。 当在Qt中使用SQLite数据库时&#xff0c;需要涉及到一些SQL语句以及Qt中的相关函数&#xf…...

开源模型应用落地-FastAPI-助力模型交互-进阶篇(一)

一、前言 FastAPI 的高级用法可以为开发人员带来许多好处。它能帮助实现更复杂的路由逻辑和参数处理&#xff0c;使应用程序能够处理各种不同的请求场景&#xff0c;提高应用程序的灵活性和可扩展性。 在数据验证和转换方面&#xff0c;高级用法提供了更精细和准确的控制&#…...

精准选择广告工具,提升推广效果

在考虑使用巨量引擎之前&#xff0c;我们首先要明白它的本质。巨量引擎是一个付费广告平台&#xff0c;包含了多种推广工具&#xff0c;如巨量ID、巨量千川、巨量本地推&#xff0c;以及企业蓝V等。很多人希望通过这个平台提升抖音账号的流量和曝光度&#xff0c;但真正有效的流…...

Swagger的原理及应用详解(六)

本系列文章简介: 在当今快速发展的软件开发领域,特别是随着微服务架构和前后端分离开发模式的普及,API(Application Programming Interface,应用程序编程接口)的设计与管理变得愈发重要。一个清晰、准确且易于理解的API文档不仅能够提升开发效率,还能促进前后端开发者之…...

世界人工智能大会今日开幕:人工智能如何成为引领发展的新引擎

人工智能如何成为引领上海发展的新引擎&#xff1f;今日&#xff08;7月4日&#xff09;开幕的2024世界人工智能大会暨人工智能全球治理高级别会议&#xff08;简称“WAIC 2024”&#xff09;将带来答案。 “新”和“全”是今年大会的亮点所在&#xff1a;“新”在于技术新&…...

tinyshop项目部署

参考软件测试之测试用例设计&#xff08;四&#xff09;_管理后台 测试用例-CSDN博客 1、下载xampp 2、修改apache和mysql的端口分别为4431 &#xff0c;8013和3306 3、访问页面&#xff1a;输入ip:端口号&#xff0c;出现以下页面即成功 4、安装tinyshop商城 将解压的tinys…...

Gemini for China 大更新,现已上架 Android APP!

官网&#xff1a;https://gemini.fostmar.online/ Android APP&#xff1a;https://gemini.fostmar.online/gemini_1.0.apk 一、Android APP 如果是 Android 设备&#xff0c;则会直接识别到并给下载链接。PC 直接对话即可。 二、聊天记录 现在 Gemini for China&#xff…...

Unity渲染管线介绍

Unity中的渲染管线渲染场景主要分为三个阶段 剔除&#xff08;Culling&#xff09; 剔除摄像机不可见对象&#xff08;视锥体剔除Frustum Culling&#xff09;和被遮挡对象&#xff08;遮挡剔除Occlusion Culling&#xff09;。 渲染&#xff08;Rendering&#xff09; 将可见…...

【UML用户指南】-31-对体系结构建模-制品图

目录 1、对源代码建模 2、对可执行程序的发布建模 3、对物理数据库建模 4、对可适应系统建模 制品图是对面向对象系统的物理方面进行建模时要用到的两种图之一。制品图展示一组制品之间的组织以及其间依赖关系。 利用制品图可以对系统的静态实现视图建模。这包括对存在于结…...

《基于 Kafka + Flink + ES 实现危急值处理措施推荐和范围校准》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; 近期刚转战 CSDN&#xff0c;会严格把控文章质量&#xff0c;绝不滥竽充数&#xff0c;欢迎多多交流。&am…...

计算机的进制转换

十进制&#xff1a;以0-9这九个数字组成。 二进制&#xff1a;由0和1两个数字组成。 八进制&#xff1a;由0-7数字组成&#xff0c;不存在8和9。 十六进制&#xff1a;由0-9和A-F组成。A-F对应的是10-15。 ____________ 十进制 1 2 3 4 5 6 7 8 9 10 二进制 0 1 10 11 1…...

String类(STL开始)

相信大家都知道STL在C中的重要性&#xff0c;作为其模板库中的一部分&#xff0c;包含了常见的数据结构和算法&#xff0c;是C的标准库 而我们今天要讲的String类&#xff08;String底层是一个字符顺序数组的顺序表对象&#xff0c;可以归类为容器&#xff09;&#xff0c;其实…...

【数据结构】单链表:数据结构中的舞者,穿梭于理论与实践的舞池

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 数据结构与算法 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 一、链表的概念和结构 1.1 链表的概念 在上一篇文章中&#xff0c;我们了解了线性表(linear list)&#xff0c;并且学习了其…...

html三级菜单

示例 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>Menu Example</title> <link re…...

【人工智能】—基于成都市各区(市)县租房价格预测建模研究

引言 随着城市化进程的加速&#xff0c;人口流动日益频繁&#xff0c;租房市场作为城市生活的重要组成部分&#xff0c;其价格波动对居民生活质量和城市经济发展具有显著影响。成都市&#xff0c;作为中国西部地区的经济、文化、交通和科技中心&#xff0c;近年来吸引了大量人…...

3213. 最小代价构造字符串

Powered by:NEFU AB-IN Link 文章目录 3213. 最小代价构造字符串题意思路代码 3213. 最小代价构造字符串 题意 给你一个字符串 target、一个字符串数组 words 以及一个整数数组 costs&#xff0c;这两个数组长度相同。 设想一个空字符串 s。 你可以执行以下操作任意次数&a…...

提取重复数据

直接上控制台代码&#xff1a; Module Module1Sub Main()Console.WriteLine("请输入数据&#xff0c;以""&#xff0c;""相隔&#xff1a;")Dim str As String Console.ReadLineDim result From x In str.Split(",")Group By x Int…...

Go语言标准库之log和三方库zap

一、Log 1.1 logger基本使用 Go语言内置的log包实现了简单的日志服务。本包也提供了一个预定义的“标准”logger&#xff0c;可以通过调用函数Print系列(Print|Printf|Println)、Fatal系列&#xff08;Fatal|Fatalf|Fatalln)、和Panic系列&#xff08;Panic|Panicf|Panicln)来…...

C语言双端队列完整实现:一行代码吃透头尾操作,算法效率拉满

一、为什么C语言实现双端队列&#xff0c;是数据结构的必学天花板&#xff1f;在C语言数据结构里&#xff0c;队列、栈都是基础中的基础&#xff0c;但真正能把灵活度、效率、内存管理三者揉到一起的&#xff0c;还得是双端队列&#xff08;deque&#xff09;。普通队列只能一头…...

从Gamma函数到泊松分布:一个概率论中的含参量积分实用案例解析

Gamma函数与泊松分布&#xff1a;概率论中的数学之美 在数据科学和机器学习的实践中&#xff0c;概率分布构成了建模的基石。当我们深入探究这些分布背后的数学原理时&#xff0c;Gamma函数以其优雅的性质和广泛的应用脱颖而出。它不仅连接了离散与连续概率世界&#xff0c;更在…...

苏州创新药20年,站上全球产业洗牌暴风眼

一个城市的创新药产业集群如何从无到有&#xff0c;又如何在全球化临界点寻找自己的位置。文&#xff5c;徐鑫编&#xff5c;任晓渔过去一年多&#xff0c;苏州是全球创新药产业版图中一个绕不过去的城市。大额海外授权交易频繁传出&#xff0c;在中国高端制造走出去的背景下&a…...

Python基础语法:常用内置函数

round()&#xff1a;四舍五入 # 省略 ndigits print(round(3.14)) # 输出 3&#xff08;int&#xff09; print(round(3.66)) # 输出 4# 指定 ndigits print(round(3.14159, 2)) # 输出 3.14&#xff08;float&#xff09; print(round(3.666, 2)) # 输出 3.67# …...

INT8量化下TVA注意力对齐精度保障方案

重磅预告&#xff1a;本专栏将独家连载系列丛书《智能体视觉技术与应用》部分精华内容&#xff0c;该书是世界首套系统阐述“因式智能体”视觉理论与实践的专著&#xff0c;特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。Bohan先生师从美国三院院士、“…...

基于LSTM自编码器的家用电器功耗异常检测系统构建指南

1. 项目概述&#xff1a;从能耗洞察到智能干预我们每天都在和各种家用电器打交道&#xff0c;从清晨唤醒你的咖啡机&#xff0c;到深夜还在默默工作的路由器。你有没有想过&#xff0c;这些看似微不足道的设备&#xff0c;其背后隐藏的能耗模式&#xff0c;其实大有文章&#x…...

AICoverGen终极指南:快速创建AI翻唱歌曲的完整教程

AICoverGen终极指南&#xff1a;快速创建AI翻唱歌曲的完整教程 【免费下载链接】AICoverGen A WebUI to create song covers with any RVC v2 trained AI voice from YouTube videos or audio files. 项目地址: https://gitcode.com/gh_mirrors/ai/AICoverGen 想要让你的…...

使用Taotoken CLI工具一键配置多开发环境下的统一模型接入点

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 使用Taotoken CLI工具一键配置多开发环境下的统一模型接入点 在团队协作或管理多个AI应用项目时&#xff0c;一个常见的痛点是每个…...

3大突破性功能:用HiveWE革新你的魔兽争霸III地图创作体验

3大突破性功能&#xff1a;用HiveWE革新你的魔兽争霸III地图创作体验 【免费下载链接】HiveWE A Warcraft III world editor. 项目地址: https://gitcode.com/gh_mirrors/hi/HiveWE 还在为传统魔兽争霸III编辑器缓慢的加载速度和复杂的操作界面而烦恼吗&#xff1f;Hive…...

《关于 AI Agent 基础设施的一些奇思妙想》

目录 目录 目录 一、AI Agent 容器 问题背景 想法思路&#xff1a;API 中转站模式 多 Agent 切换 二、手机端操控 AI Agent&#xff08;手机与电脑互联&#xff09; 三、AI 开发依赖管理工具 总结 最近 AI Agent 越来越火&#xff0c;我作为一个重度使用者&#xff0c…...