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

}
相关推荐
zhangphil27 分钟前
Android ValueAnimator ImageView animate() rotation,Kotlin
android·kotlin
徊忆羽菲1 小时前
CentOS7使用源码安装PHP8教程整理
android
编程、小哥哥2 小时前
python操作mysql
android·python
Couvrir洪荒猛兽3 小时前
Android实训十 数据存储和访问
android
五味香5 小时前
Java学习,List 元素替换
android·java·开发语言·python·学习·golang·kotlin
十二测试录5 小时前
【自动化测试】—— Appium使用保姆教程
android·经验分享·测试工具·程序人生·adb·appium·自动化
Couvrir洪荒猛兽7 小时前
Android实训九 数据存储和访问
android
aloneboyooo7 小时前
Android Studio安装配置
android·ide·android studio
Jacob程序员7 小时前
leaflet绘制室内平面图
android·开发语言·javascript
2401_897907868 小时前
10天学会flutter DAY2 玩转dart 类
android·flutter