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