Android 遥控器

遥控器源码
java 复制代码
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;
    //中心X
    private float cx;
    //中心Y
    private 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);
    }

    @Override
    protected 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;
    }

    @Override
    public 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) {

        }
    }

    @Override
    protected 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;
    }

}
相关推荐
云手机管家32 分钟前
自动化脚本开发:Python调用云手机API实现TikTok批量内容发布
android·网络安全·智能手机·架构·自动化
咕噜企业签名分发-淼淼1 小时前
iOS苹果和Android安卓测试APP应用程序的区别差异
android·ios·cocoa
IT从业者张某某1 小时前
信奥赛-刷题笔记-栈篇-T2-P1165日志分析0519
android·java·笔记
androidwork3 小时前
Kotlin与物联网(IoT):Android Things开发探索
android·物联网·kotlin
橙子199110163 小时前
在 Kotlin 中,什么是内联函数?有什么作用?
android·开发语言·kotlin
悠哉清闲3 小时前
Kotlin 协程 (一)
android·开发语言·kotlin
草明4 小时前
使用 adb 命令截取 Android 设备的屏幕截图
android·adb
.生产的驴4 小时前
SpringBoot 商城系统高并发引起的库存超卖库存问题 乐观锁 悲观锁 抢购 商品秒杀 高并发
android·java·数据库·spring boot·后端·spring·maven
xihaowen5 小时前
Android Edge-to-Edge
android·前端·edge
WenGyyyL6 小时前
《Android 应用开发基础教程》——第十三章:权限管理机制与运行时权限请求(以拍照/存储为例)
android·java·权限·极限编程