Skip to content

Commit 03cd505

Browse files
feat(*): 解决自定义控件性能问题
1 parent 461a4c5 commit 03cd505

File tree

11 files changed

+405
-37
lines changed

11 files changed

+405
-37
lines changed

app/src/main/java/com/pengxh/kt/lib/MainActivity.kt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@ package com.pengxh.kt.lib
22

33
import android.os.Bundle
44
import com.pengxh.kt.lite.base.KotlinBaseActivity
5+
import com.pengxh.kt.lite.extensions.show
6+
import com.pengxh.kt.lite.widget.SteeringWheelView
7+
import kotlinx.android.synthetic.main.activity_main.*
58

69
class MainActivity : KotlinBaseActivity() {
710

811
private val kTag = "MainActivity"
12+
private val context = this@MainActivity
913

1014
override fun initLayoutView(): Int = R.layout.activity_main
1115

@@ -22,6 +26,43 @@ class MainActivity : KotlinBaseActivity() {
2226
}
2327

2428
override fun initEvent() {
29+
steeringWheelView.setOnWheelTouchListener(object : SteeringWheelView.OnWheelTouchListener {
30+
override fun onCenterClicked() {
31+
"onCenterClicked".show(context)
32+
}
2533

34+
override fun onLeftTurn() {
35+
"onLeftTurn".show(context)
36+
}
37+
38+
override fun onTopTurn() {
39+
"onTopTurn".show(context)
40+
}
41+
42+
override fun onRightTurn() {
43+
"onRightTurn".show(context)
44+
}
45+
46+
override fun onBottomTurn() {
47+
"onBottomTurn".show(context)
48+
}
49+
50+
override fun onActionTurnUp(dir: SteeringWheelView.Direction) {
51+
when (dir) {
52+
SteeringWheelView.Direction.LEFT -> {
53+
"LEFT onActionTurnUp".show(context)
54+
}
55+
SteeringWheelView.Direction.TOP -> {
56+
"TOP onActionTurnUp".show(context)
57+
}
58+
SteeringWheelView.Direction.RIGHT -> {
59+
"RIGHT onActionTurnUp".show(context)
60+
}
61+
SteeringWheelView.Direction.BOTTOM -> {
62+
"BOTTOM onActionTurnUp".show(context)
63+
}
64+
}
65+
}
66+
})
2667
}
2768
}

app/src/main/res/layout/activity_main.xml

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,14 @@
55
android:layout_height="match_parent"
66
android:orientation="vertical">
77

8-
<com.pengxh.kt.lite.widget.SteeringWheelController
9-
android:id="@+id/steeringWheelController"
10-
android:layout_width="match_parent"
11-
android:layout_height="0dp"
12-
android:layout_weight="1"
13-
app:controller_backgroundColor="@color/black"
14-
app:controller_borderColor="@color/red"
15-
app:controller_borderStroke="@dimen/dp_5"
16-
app:controller_outerCircleDiameter="@dimen/dp_200" />
17-
188
<com.pengxh.kt.lite.widget.SteeringWheelView
199
android:id="@+id/steeringWheelView"
2010
android:layout_width="match_parent"
21-
android:layout_height="0dp"
22-
android:layout_weight="1"
11+
android:layout_height="match_parent"
12+
android:background="@color/white"
13+
android:gravity="center"
2314
app:ctrl_backgroundColor="@color/white"
2415
app:ctrl_borderColor="#64BFEB"
2516
app:ctrl_borderStroke="@dimen/dp_5"
26-
app:ctrl_diameter="@dimen/dp_200"
27-
app:ctrl_directionColor="#2A68BF"
28-
app:ctrl_directionDiameter="@dimen/dp_15"
29-
app:ctrl_switchColor="@color/white" />
17+
app:ctrl_diameter="@dimen/dp_200" />
3018
</LinearLayout>

app/src/main/res/layout/fragment_first.xml

Lines changed: 0 additions & 12 deletions
This file was deleted.

lite/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ dependencies {
3333
implementation 'androidx.core:core-ktx:1.9.0'
3434
implementation 'androidx.appcompat:appcompat:1.6.1'
3535
implementation 'androidx.cardview:cardview:1.0.0'
36-
implementation "androidx.recyclerview:recyclerview:1.2.1"
36+
implementation "androidx.recyclerview:recyclerview:1.3.0"
3737
implementation 'io.reactivex:rxjava:1.3.8'
3838
implementation 'io.reactivex:rxandroid:1.2.1'
3939
implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1'

lite/src/main/java/com/pengxh/kt/lite/widget/SteeringWheelController.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ import kotlin.math.sqrt
1313
/**
1414
* 方向盘控件
1515
* */
16+
@Deprecated(
17+
"废弃,不建议使用,有性能问题",
18+
replaceWith = ReplaceWith("SteeringWheelView"),
19+
level = DeprecationLevel.WARNING
20+
)
1621
class SteeringWheelController constructor(context: Context, attrs: AttributeSet) :
1722
View(context, attrs), View.OnTouchListener {
1823
//画布中心x
Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
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+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<selector xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<item android:state_pressed="false">
5+
<shape android:shape="oval">
6+
<solid android:color="#64BFEB" />
7+
</shape>
8+
</item>
9+
10+
<item android:state_pressed="true">
11+
<shape android:shape="oval">
12+
<!-- 点击按钮时候改变背景色50% -->
13+
<solid android:color="#8064BFEB" />
14+
</shape>
15+
</item>
16+
</selector>

0 commit comments

Comments
 (0)