Android 遥控器

在这里插入图片描述

遥控器源码
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RadialGradient;
import android.graphics.Region;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;import androidx.annotation.Nullable;import com.anbao.monitor.robot.schemas.Direction;/*** 方向盘控制*/
public class SteeringView extends View {private Paint paint;//第1个圆颜色private int circle1Color = Color.WHITE;//第2个圆颜色private int circle2Color = Color.parseColor("#4D5D6E");//第3个圆颜色private int circle3Color = Color.WHITE;//第4个圆颜色private int circle4Color = Color.GRAY;//线条颜色private int strokeColor = Color.WHITE;//左边三角形颜色private int leftTriangleColor = Color.WHITE;//右边三角形颜色private int rightTriangleColor = Color.WHITE;//上边三角形颜色private int topTriangleColor = Color.WHITE;//下边三角形颜色private int bottomTriangleColor = Color.WHITE;//第一个圆和第二个圆间距private float padding = 8;//线条宽度private float strokeWidth = 5;//第三个圆比例private float circle3RadiusFactor = 0.4f;//第4个圆比例private float circle4RadiusFactor = 0.3f;//三角形边长private float triangleLength = 100;//三角形和第二个圆间距private float trianglePadding = 90;//中心Xprivate float cx;//中心Yprivate float cy;//半径private float radius;//高度protected float height;//左点击区域private Region leftRegion;//右点击区域private Region rightRegion;//上点击区域private Region topRegion;//下点击区域private Region bottomRegion;public SteeringView(Context context) {this(context, null);}public SteeringView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public SteeringView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);paint = new Paint();paint.setAntiAlias(true);paint.setColor(circle2Color);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);height = getMeasuredHeight();radius = Math.min(getMeasuredHeight(), getMeasuredWidth()) / 2f;cx = getMeasuredWidth() / 2f;cy = getMeasuredHeight() / 2f;trianglePadding = radius * 0.2f;triangleLength = radius * 0.22f;}@Overridepublic boolean onTouchEvent(MotionEvent event) {float x = event.getX();float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (leftRegion.contains((int) x, (int) y)) {leftTriangleColor = Color.RED;onSteeringDirection(Direction.LEFT);} else if (rightRegion.contains((int) x, (int) y)) {rightTriangleColor = Color.RED;onSteeringDirection(Direction.RIGHT);} else if (topRegion.contains((int) x, (int) y)) {topTriangleColor = Color.RED;onSteeringDirection(Direction.FORWARD);} else if (bottomRegion.contains((int) x, (int) y)) {bottomTriangleColor = Color.RED;onSteeringDirection(Direction.BACKWARDS);}break;case MotionEvent.ACTION_UP:leftTriangleColor = Color.WHITE;rightTriangleColor = Color.WHITE;topTriangleColor = Color.WHITE;bottomTriangleColor = Color.WHITE;break;}invalidate();return true;}/*** 方向控制** @param direction 方向*/private void onSteeringDirection(Direction direction) {//左转if (direction == Direction.LEFT) {}//右转else if (direction == Direction.RIGHT) {}//前进else if (direction == Direction.FORWARD) {}//后退else if (direction == Direction.BACKWARDS) {}}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);paint.setShader(null);//外圆paint.setStyle(Paint.Style.FILL);paint.setColor(circle1Color);canvas.drawCircle(cx, cy, radius, paint);//内圆paint.setColor(circle2Color);canvas.drawCircle(cx, cy, radius - padding, paint);//中心圆paint.setColor(circle3Color);canvas.drawCircle(cx, cy, radius * circle3RadiusFactor, paint);//左->右斜线paint.setColor(strokeColor);paint.setStrokeWidth(strokeWidth);float radians = (float) Math.toRadians(45);float lsx = cx - (float) ((radius - padding) * Math.cos(radians));float lsy = height / 2.0f - (float) ((radius - padding) * Math.sin(radians));float lex = cx + (float) ((radius - padding) * Math.cos(radians));float ley = height / 2.0f + (float) ((radius - padding) * Math.sin(radians));canvas.drawLine(lsx, lsy, lex, ley, paint);//右->左斜线float rsx = cx + (float) ((radius - padding) * Math.cos(radians));float rsy = height / 2.0f - (float) ((radius - padding) * Math.sin(radians));float rex = cx - (float) ((radius - padding) * Math.cos(radians));float rey = height / 2.0f + (float) ((radius - padding) * Math.sin(radians));canvas.drawLine(rsx, rsy, rex, rey, paint);//绘制左边箭头drawLeftTriangle(canvas);//绘制右边箭头drawRightTriangle(canvas);//绘制上方箭头drawTopTriangle(canvas);//绘制下方箭头drawBottomTriangle(canvas);//按下区域leftRegion = buildLeftRegion();rightRegion = buildRightRegion();topRegion = buildTopRegion();bottomRegion = buildBottomRegion();//外发光圆int[] colors = {Color.TRANSPARENT, circle4Color};float[] stops = {0.3f, 1.0f};RadialGradient gradient = new RadialGradient(cx, cy, radius * 0.3f, colors, stops, Shader.TileMode.CLAMP);paint.setShader(gradient);canvas.drawCircle(cx, cy, radius * circle4RadiusFactor, paint);}/*** 绘制左边三角形** @param canvas*/private void drawLeftTriangle(Canvas canvas) {paint.setStrokeCap(Paint.Cap.ROUND);paint.setStyle(Paint.Style.FILL);paint.setColor(leftTriangleColor);Path path = new Path();path.moveTo(cx - radius + trianglePadding, cy);path.lineTo(cx - radius + trianglePadding + triangleLength, cy - triangleLength / 2f);path.lineTo(cx - radius + trianglePadding + triangleLength, cy + triangleLength / 2f);path.lineTo(cx - radius + trianglePadding, cy);canvas.drawPath(path, paint);}/*** 绘制右边三角形** @param canvas*/private void drawRightTriangle(Canvas canvas) {paint.setStrokeCap(Paint.Cap.ROUND);paint.setStyle(Paint.Style.FILL);paint.setColor(rightTriangleColor);Path path = new Path();path.moveTo(cx + radius - trianglePadding, cy);path.lineTo(cx + radius - trianglePadding - triangleLength, cy - triangleLength / 2f);path.lineTo(cx + radius - trianglePadding - triangleLength, cy + triangleLength / 2f);path.lineTo(cx + radius - trianglePadding, cy);canvas.drawPath(path, paint);}/*** 绘制上方三角形** @param canvas*/private void drawTopTriangle(Canvas canvas) {paint.setStrokeCap(Paint.Cap.ROUND);paint.setStyle(Paint.Style.FILL);paint.setColor(topTriangleColor);Path path = new Path();path.moveTo(cx, cy - radius + trianglePadding);path.lineTo(cx + triangleLength / 2f, cy - radius + trianglePadding + triangleLength);path.lineTo(cx - triangleLength / 2f, cy - radius + trianglePadding + triangleLength);path.lineTo(cx, cy - radius + trianglePadding);canvas.drawPath(path, paint);}/*** 绘制下方箭头** @param canvas*/private void drawBottomTriangle(Canvas canvas) {paint.setStrokeCap(Paint.Cap.ROUND);paint.setStyle(Paint.Style.FILL);paint.setColor(bottomTriangleColor);Path path = new Path();path.moveTo(cx, cy + radius - trianglePadding);path.lineTo(cx + triangleLength / 2f, cy + radius - trianglePadding - triangleLength);path.lineTo(cx - triangleLength / 2f, cy + radius - trianglePadding - triangleLength);path.lineTo(cx, cy + radius - trianglePadding);canvas.drawPath(path, paint);}/*** 构建左边区域** @return*/private Region buildLeftRegion() {Region region = new Region();Path path = new Path();path.moveTo(cx, cy);path.addArc(cx - radius, cy - radius, cx + radius, cy + radius, -135, -90);path.lineTo(cx, cy);paint.setColor(Color.RED);Region clip = new Region((int) (cx - radius), (int) (cy - radius), (int) (cx - radius * circle3RadiusFactor), (int) (cy + radius));region.setPath(path, clip);return region;}/*** 构建右边区域** @return*/private Region buildRightRegion() {Region region = new Region();Path path = new Path();path.moveTo(cx, cy);path.addArc(cx - radius, cy - radius, cx + radius, cy + radius, -45, 90);path.lineTo(cx, cy);paint.setColor(Color.RED);Region clip = new Region((int) (cx + radius * circle3RadiusFactor), (int) (cy - radius), (int) (cx + radius), (int) (cy + radius));region.setPath(path, clip);return region;}/*** 构建上方区域** @return*/private Region buildTopRegion() {Region region = new Region();Path path = new Path();path.moveTo(cx, cy);path.addArc(cx - radius, cy - radius, cx + radius, cy + radius, -45, -90);path.lineTo(cx, cy);paint.setColor(Color.RED);Region clip = new Region((int) (cx - radius), (int) (cy - radius), (int) (cx + radius), (int) (cy - radius * circle3RadiusFactor));region.setPath(path, clip);return region;}/*** 构建下方区域** @return*/private Region buildBottomRegion() {Region region = new Region();Path path = new Path();path.moveTo(cx, cy);path.addArc(cx - radius, cy - radius, cx + radius, cy + radius, 45, 90);path.lineTo(cx, cy);paint.setColor(Color.RED);Region clip = new Region((int) (cx - radius), (int) (cy + radius * circle3RadiusFactor), (int) (cx + radius), (int) (cy + radius));region.setPath(path, clip);return region;}}

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

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

相关文章

个微API二次开发

通过 E云API 可以实现 个性化微信功能 (例:营销系统、云发单助手、社群管家webot、客服系统等),用来自动管理微信消息。 可开发的功能包括但不限于: 好友管理: 添加好友、删除好友、修改备注、创建标签、获…

云动态摘要 2024-06-28

给您带来云厂商的最新动态,最新产品资讯和最新优惠更新。 最新优惠与活动 [新客专享]WeData 限时特惠 腾讯云 2024-06-21 数据分类分级管理,构建数据安全屏障 ,仅需9.9元! 云服务器ECS试用产品续用 阿里云 2024-04-14 云服务器…

VMware虚拟机三种网络模式设置 - Host-Only(仅主机模式)

一、前言 在之前的《Bridged(桥接模式)》、《NAT(网络地址转换模式)》中,我详细介绍了虚拟机网络模式设置中的桥接模式与网络地址转换模式。今天详细讲解一下Host-Only(仅主机模式)。 在VMware虚…

Java代码基础算法练习-判断学生成绩等级-2024.06.28

任务描述: 输入一个学生的成绩(成绩大于等于 0 并小于等于 100),根据成绩判断学生成绩的等级。 60 分以下不及格;60-70 分为及格;70-80 分为中等;80-90 分为良好;90 分以上为优秀。 …

版本控制工具-git分支管理

目录 前言一、git分支管理基本命令1.1 基本命令2.1 实例 二、git分支合并冲突解决三、git merge命令与git rebase命令对比 前言 本篇文章介绍git分支管理的基本命令,并说明如何解决git分支合并冲突,最后说明git merge命令与git rebase命令的区别。 一、…

Excel 宏录制与VBA编程 —— 15、MsgBox参数详解

Msgbox参数具体如下 Msgbox参数使用1 Msgbox参数使用2(返回值示例) &ensp ;###### 关注 笔者 - jxd

绿色网络设计方法

1.绿色网络设计思路 绿色网络的构建,不仅要从网络设备的节能环保下功夫,更要从网络的方案设计上做文章。虽说降低设备的能耗可为网络的节能环保起到积极作用,但网络架构优化有可能使整个网络节能环保有一个质的飞跃。 网络设备作为网络设计方…

Spring Boot与RabbitMQ的集成应用

Spring Boot与RabbitMQ的集成应用 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨如何在Spring Boot应用中集成和使用RabbitMQ,实现消…

adb server version (41) doesn‘t match this client (39); killing...

在运行adb kill-server和 adb start-server时报如下错误: uos@uos-PC:~$ adb kill-server uos@uos-PC:~$ adb start-server adb server version (41) doesnt match this client (39); killing..

Linux系统之部署linkding书签管理器

Linux系统之部署linkding书签管理器 一、linkding介绍1.1 linkding简介1.2 linkding特点二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本四、部署Node.js 环境4.1 下载Node.js安装包4.2 解压Node.js安装包4.3 …

C++ RTTI: 让你的代码更灵活

RTTI是什么? RTTI全称是Runtime Type Information,顾名思义就是在程序运行时获取类型信息的机制。它允许我们在运行时动态地查询对象的类型,甚至进行安全的类型转换。 C中提供了两个主要的RTTI操作符: typeid操作符: 它可以返回一个type_info对象,该对象包含了类型的名称和…

深入理解动态代理:JDK动态代理与CGLIB动态代理

引言 在软件开发中,动态代理是一种强大的技术,它允许在运行时创建代理对象,从而为原对象添加额外的功能。Java中主要有两种动态代理机制:JDK动态代理和CGLIB动态代理。本篇文章将详细介绍这两种动态代理的概念、实现方式、应用场…

ANSYS Electronics 电磁场仿真工具下载安装,ANSYS Electronics强大的功能和灵活性

ANSYS Electronics无疑是一款在电磁场仿真领域表现卓越的软件工具。它凭借强大的功能和灵活性,帮助用户在产品设计阶段就能精确预测和优化电磁场性能,从而极大地降低了实际测试成本,并显著提升了产品的可靠性。 这款软件不仅在电子设计领域有…

Java数组的初始化方法

Java数组的初始化方法 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!在Java编程中,数组是一种非常基础也非常重要的数据结构,它能够存储…

linux中awk,sed, grep使用(待补充)

《linux私房菜》这本书中将sed和awk一同归为行的修改这一点,虽然对,但不利于实际处理问题时的思考。因为这样的话,当我们实际处理问题时,遇到比如说统计文本打印内容时,我们选择sed还是awk进行处理呢? 也因…

VS Code 配置cmake(Linux环境)

通过sudo apt install cmake在linux上安装cmake 在Vs Code中安装这两个插件 通过命令whereis cmake获取linux中cmake的路径信息 右键CMake Tools右下角齿轮标志,选择扩展设置(Extension Settings) 注意要设置的是本地,还是远程连接…

Linux 进程间通讯

Linux IPC 方式 在Linux系统中,进程间通信(IPC)是多个运行中的程序或进程之间交换数据和信息的关键机制。Linux提供了多种IPC机制,每种机制都有其特定的用途和优势。以下是Linux上主要的IPC通信方式: 管道&#xff08…

前后端分离对软件行业及架构设计的影响

在软件开发领域,前后端分离是一种越来越流行的架构设计模式。这种方法将用户界面(前端)与服务器逻辑(后端)分离开来,允许它们独立开发、测试和部署。本文将探讨前后端分离对软件行业和架构设计的影响&#…

开发Qt上位机获取阿里云IOT设备数据(开发上位机对接阿里云IOT平台)

一、前言 随着物联网技术的快速发展,越来越多的设备开始接入互联网,实现远程监控和管理。为了方便用户实时查看设备的运行状态和数据,本文将介绍如何使用Qt框架开发一款上位机软件,调用阿里云物联网平台的API接口,获取设备最新上传的实时数据,并在Qt设计的软件界面上展示…

添加用户页面(Flask+前端+MySQL整合)

首先导入Flask库和pymysql库。Flask用于创建Web应用程序,pymysql用于连接和操作MySQL数据库。 from flask import Flask, render_template, request import pymysql创建一个Flask应用实例。__name__参数告诉Flask使用当前模块作为应用的名称。 app Flask(__name_…