遥控器源码
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) ;
}
@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 ;
}
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) ;
}
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;
}
}