遥控器源码
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;private int circle1Color = Color.WHITE;private int circle2Color = Color.parseColor("#4D5D6E");private int circle3Color = Color.WHITE;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;private float circle4RadiusFactor = 0.3f;private float triangleLength = 100;private float trianglePadding = 90;private float cx;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);}@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;}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);}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);}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);}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);}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);}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;}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;}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;}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;}}