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;
    }

}
相关推荐
每次的天空4 小时前
Android学习总结之算法篇四(字符串)
android·学习·算法
x-cmd5 小时前
[250331] Paozhu 发布 1.9.0:C++ Web 框架,比肩脚本语言 | DeaDBeeF 播放器发布 1.10.0
android·linux·开发语言·c++·web·音乐播放器·脚本语言
tangweiguo030519879 小时前
Android BottomNavigationView 完全自定义指南:图标、文字颜色与选中状态
android
遥不可及zzz10 小时前
Android 应用程序包的 adb 命令
android·adb
无知的前端10 小时前
Flutter 一文精通Isolate,使用场景以及示例
android·flutter·性能优化
_一条咸鱼_10 小时前
Android Compose 入门之字符串与本地化深入剖析(五十三)
android
ModestCoder_11 小时前
将一个新的机器人模型导入最新版isaacLab进行训练(以unitree H1_2为例)
android·java·机器人
robin_suli11 小时前
Spring事务的传播机制
android·java·spring
鸿蒙布道师12 小时前
鸿蒙NEXT开发对象工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
Harrison_zhu13 小时前
Ubuntu18.04 编译 Android7.1代码报错
android