1
+ package com.pengxh.kt.lite.widget
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.Context
5
+ import android.graphics.Canvas
6
+ import android.graphics.Color
7
+ import android.graphics.Paint
8
+ import android.graphics.RectF
9
+ import android.util.AttributeSet
10
+ import android.view.LayoutInflater
11
+ import android.view.MotionEvent
12
+ import android.widget.ImageButton
13
+ import android.widget.RelativeLayout
14
+ import com.pengxh.kt.lite.R
15
+
16
+
17
+ /* *
18
+ * 方向盘控件
19
+ * */
20
+ @SuppressLint(" ClickableViewAccessibility" )
21
+ class SteeringWheelView constructor(context : Context , attrs : AttributeSet ) :
22
+ RelativeLayout (context, attrs) {
23
+
24
+ // 画布中心x
25
+ private var canvasCenterX = 0
26
+
27
+ // 画布中心y
28
+ private var canvasCenterY = 0
29
+
30
+ // 控件直径
31
+ private val diameter: Float
32
+
33
+ // Paint
34
+ private val backgroundPaint: Paint
35
+ private val borderPaint: Paint
36
+ private val directionPaint: Paint
37
+
38
+ // 各控件使用状态
39
+ private var leftTurn = false
40
+ private var topTurn = false
41
+ private var rightTurn = false
42
+ private var bottomTurn = false
43
+
44
+ // 外圆区域
45
+ private lateinit var outerCircleRectF: RectF
46
+
47
+ // 线条粗细
48
+ private val borderStroke: Float
49
+
50
+ init {
51
+ val type = context.obtainStyledAttributes(attrs, R .styleable.SteeringWheelView )
52
+ diameter = type.getDimension(
53
+ R .styleable.SteeringWheelView_ctrl_diameter , 200f
54
+ )
55
+ val borderColor = type.getColor(
56
+ R .styleable.SteeringWheelView_ctrl_borderColor , Color .CYAN
57
+ )
58
+ val backgroundColor = type.getColor(
59
+ R .styleable.SteeringWheelView_ctrl_backgroundColor , Color .WHITE
60
+ )
61
+ borderStroke = type.getDimension(
62
+ R .styleable.SteeringWheelView_ctrl_borderStroke , 5f
63
+ )
64
+ type.recycle()
65
+
66
+ borderPaint = Paint ()
67
+ borderPaint.isAntiAlias = true
68
+ borderPaint.isDither = true
69
+ borderPaint.style = Paint .Style .STROKE
70
+ borderPaint.strokeWidth = borderStroke
71
+ borderPaint.color = borderColor
72
+
73
+ backgroundPaint = Paint ()
74
+ backgroundPaint.isAntiAlias = true
75
+ backgroundPaint.isDither = true
76
+ backgroundPaint.style = Paint .Style .FILL
77
+ backgroundPaint.color = backgroundColor
78
+
79
+ directionPaint = Paint ()
80
+ directionPaint.isAntiAlias = true
81
+ directionPaint.isDither = true
82
+ directionPaint.style = Paint .Style .FILL
83
+ directionPaint.color = borderColor
84
+
85
+ val layoutParams = LayoutParams (diameter.toInt(), diameter.toInt())
86
+
87
+ val view = LayoutInflater .from(context).inflate(R .layout.widget_view_steering_wheel, this )
88
+
89
+ val rootView = view.findViewById<RelativeLayout >(R .id.rootView)
90
+ rootView.layoutParams = layoutParams
91
+
92
+ val leftButton = view.findViewById<ImageButton >(R .id.leftButton)
93
+ leftButton.setOnTouchListener { _, event ->
94
+ when (event.action) {
95
+ MotionEvent .ACTION_DOWN -> {
96
+ leftTurn = true
97
+ listener?.onLeftTurn()
98
+ }
99
+ MotionEvent .ACTION_UP -> {
100
+ leftTurn = false
101
+ listener?.onActionTurnUp(Direction .LEFT )
102
+ }
103
+ }
104
+ postInvalidate()
105
+ true
106
+ }
107
+
108
+ view.findViewById<ImageButton >(R .id.topButton).setOnTouchListener { _, event ->
109
+ when (event.action) {
110
+ MotionEvent .ACTION_DOWN -> {
111
+ topTurn = true
112
+ listener?.onTopTurn()
113
+ }
114
+ MotionEvent .ACTION_UP -> {
115
+ topTurn = false
116
+ listener?.onActionTurnUp(Direction .TOP )
117
+ }
118
+ }
119
+ postInvalidate()
120
+ true
121
+ }
122
+ view.findViewById<ImageButton >(R .id.rightButton).setOnTouchListener { _, event ->
123
+ when (event.action) {
124
+ MotionEvent .ACTION_DOWN -> {
125
+ rightTurn = true
126
+ listener?.onRightTurn()
127
+ }
128
+ MotionEvent .ACTION_UP -> {
129
+ rightTurn = false
130
+ listener?.onActionTurnUp(Direction .RIGHT )
131
+ }
132
+ }
133
+ postInvalidate()
134
+ true
135
+ }
136
+ view.findViewById<ImageButton >(R .id.bottomButton).setOnTouchListener { _, event ->
137
+ when (event.action) {
138
+ MotionEvent .ACTION_DOWN -> {
139
+ bottomTurn = true
140
+ listener?.onBottomTurn()
141
+ }
142
+ MotionEvent .ACTION_UP -> {
143
+ bottomTurn = false
144
+ listener?.onActionTurnUp(Direction .BOTTOM )
145
+ }
146
+ }
147
+ postInvalidate()
148
+ true
149
+ }
150
+ view.findViewById<ImageButton >(R .id.centerButton).setOnClickListener {
151
+ listener?.onCenterClicked()
152
+ }
153
+ }
154
+
155
+ override fun onSizeChanged (w : Int , h : Int , oldw : Int , oldh : Int ) {
156
+ super .onSizeChanged(w, h, oldw, oldh)
157
+ // 圆心位置
158
+ canvasCenterX = w shr 1
159
+ canvasCenterY = h shr 1
160
+
161
+ val outerCircleRadius = diameter.toInt() shr 1 // 半径
162
+
163
+ // 大外圈区域
164
+ outerCircleRectF = RectF (
165
+ (canvasCenterX - outerCircleRadius).toFloat(),
166
+ (canvasCenterY - outerCircleRadius).toFloat(),
167
+ (canvasCenterX + outerCircleRadius).toFloat(),
168
+ (canvasCenterY + outerCircleRadius).toFloat()
169
+ )
170
+ }
171
+
172
+ override fun onDraw (canvas : Canvas ) {
173
+ super .onDraw(canvas)
174
+ val outerCircleRadius = diameter.toInt() shr 1 // 半径
175
+ // 背景
176
+ canvas.drawCircle(
177
+ canvasCenterX.toFloat(),
178
+ canvasCenterY.toFloat(),
179
+ outerCircleRadius.toFloat(),
180
+ backgroundPaint
181
+ )
182
+
183
+ // 外圆圆圈
184
+ canvas.drawCircle(
185
+ canvasCenterX.toFloat(),
186
+ canvasCenterY.toFloat(),
187
+ outerCircleRadius.toFloat(),
188
+ borderPaint
189
+ )
190
+
191
+ if (leftTurn) {
192
+ canvas.drawArc(
193
+ outerCircleRectF, (90 * 2 - 45 ).toFloat(), 90f , false , directionPaint
194
+ )
195
+ }
196
+
197
+ if (topTurn) {
198
+ canvas.drawArc(
199
+ outerCircleRectF, (90 * 3 - 45 ).toFloat(), 90f , false , directionPaint
200
+ )
201
+ }
202
+
203
+ if (rightTurn) {
204
+ canvas.drawArc(outerCircleRectF, - 45f , 90f , false , directionPaint)
205
+ }
206
+
207
+ if (bottomTurn) {
208
+ canvas.drawArc(outerCircleRectF, 45f , 90f , false , directionPaint)
209
+ }
210
+ }
211
+
212
+ enum class Direction {
213
+ LEFT , TOP , RIGHT , BOTTOM
214
+ }
215
+
216
+ private var listener: OnWheelTouchListener ? = null
217
+
218
+ fun setOnWheelTouchListener (listener : OnWheelTouchListener ? ) {
219
+ this .listener = listener
220
+ }
221
+
222
+ interface OnWheelTouchListener {
223
+ /* *
224
+ * 中间
225
+ */
226
+ fun onCenterClicked ()
227
+
228
+ /* *
229
+ * 左
230
+ */
231
+ fun onLeftTurn ()
232
+
233
+ /* *
234
+ * 上
235
+ */
236
+ fun onTopTurn ()
237
+
238
+ /* *
239
+ * 右
240
+ */
241
+ fun onRightTurn ()
242
+
243
+ /* *
244
+ * 下
245
+ */
246
+ fun onBottomTurn ()
247
+
248
+ /* *
249
+ * 松开
250
+ */
251
+ fun onActionTurnUp (dir : Direction )
252
+ }
253
+ }
0 commit comments