Skip to content

Commit 8a6c418

Browse files
refactor(*): 优化AirDashBoardView
1 parent 59608e0 commit 8a6c418

File tree

4 files changed

+47
-141
lines changed

4 files changed

+47
-141
lines changed

app/src/main/java/com/pengxh/kt/lib/fragments/widget/AirDashBoardViewFragment.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.pengxh.kt.lib.fragments.widget
22

3-
import android.graphics.Color
43
import android.os.Bundle
54
import android.view.LayoutInflater
65
import android.view.ViewGroup
@@ -20,13 +19,7 @@ class AirDashBoardViewFragment : KotlinBaseFragment<FragmentWidgetAirDashBoardVi
2019
}
2120

2221
override fun initOnCreate(savedInstanceState: Bundle?) {
23-
binding.airDashBoardView
24-
.setMaxValue(500)
25-
.setCenterText("")
26-
.setAirRingForeground(Color.GREEN)
27-
.setAirCenterTextColor(Color.RED)
28-
.setAirCurrentValueColor(Color.BLUE)
29-
.setCurrentValue(255)
22+
binding.airDashBoardView.setCenterText("").setCurrentValue(455)
3023
}
3124

3225
override fun observeRequestState() {

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,10 @@
1212
android:id="@+id/airDashBoardView"
1313
android:layout_width="wrap_content"
1414
android:layout_height="wrap_content"
15-
app:air_center_textColor="@color/red"
16-
app:air_center_textSize="@dimen/sp_18"
17-
app:air_current_valueColor="@color/mainColor"
18-
app:air_current_valueSize="@dimen/sp_24"
15+
app:air_center_text_color="@color/red"
16+
app:air_center_text_size="@dimen/sp_18"
1917
app:air_ring_background="@color/mainBackground"
18+
app:air_ring_foreground="@color/purple_500"
2019
app:air_ring_radius="@dimen/dp_100"
21-
app:air_ring_stroke="@dimen/dp_7"
22-
app:air_valueColor="@color/gray"
23-
app:air_valueSize="@dimen/sp_14" />
20+
app:air_ring_stroke="@dimen/dp_15" />
2421
</LinearLayout>

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

Lines changed: 39 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,21 @@ import android.graphics.Color
77
import android.graphics.Paint
88
import android.graphics.Rect
99
import android.graphics.RectF
10-
import android.os.Handler
11-
import android.os.Message
1210
import android.text.TextPaint
1311
import android.util.AttributeSet
1412
import android.view.View
15-
import androidx.annotation.ColorInt
1613
import com.pengxh.kt.lite.R
1714
import com.pengxh.kt.lite.extensions.dp2px
18-
import com.pengxh.kt.lite.utils.WeakReferenceHandler
19-
import kotlinx.coroutines.CoroutineScope
20-
import kotlinx.coroutines.Dispatchers
21-
import kotlinx.coroutines.delay
22-
import kotlinx.coroutines.launch
23-
import kotlinx.coroutines.withContext
15+
import com.pengxh.kt.lite.extensions.sp2px
2416

2517
/**
2618
* 空气污染指数表盘,仿HUAWEI天气
2719
*
2820
* binding.airDashBoardView
29-
* .setMaxValue(500)
3021
* .setCenterText("优")
31-
* .setAirRingForeground(Color.GREEN)
32-
* .setAirCenterTextColor(Color.RED)
33-
* .setAirCurrentValueColor(Color.BLUE)
3422
* .setCurrentValue(255)
3523
*/
36-
class AirDashBoardView constructor(context: Context, attrs: AttributeSet) : View(context, attrs),
37-
Handler.Callback {
24+
class AirDashBoardView constructor(context: Context, attrs: AttributeSet) : View(context, attrs) {
3825

3926
//View中心X坐标
4027
private var centerX = 0f
@@ -48,19 +35,17 @@ class AirDashBoardView constructor(context: Context, attrs: AttributeSet) : View
4835
private val ringRadius: Int
4936
private lateinit var guidePaint: Paint
5037

51-
//表盘圆弧背景色
38+
//表盘圆弧色
5239
private val background: Int
40+
private val foreground: Int
5341
private val ringStroke: Int
5442
private val ringRectF: RectF
5543
private lateinit var ringPaint: Paint
5644

5745
//阈值
58-
private val thresholdTextSize: Int
59-
private val thresholdColor: Int
6046
private lateinit var thresholdPaint: TextPaint
6147

62-
private val weakReferenceHandler by lazy { WeakReferenceHandler(this) }
63-
private val currentValueTextSize: Int
48+
private val centerTextColor: Int
6449
private val centerTextSize: Int
6550

6651
//当前污染物测量值
@@ -76,8 +61,7 @@ class AirDashBoardView constructor(context: Context, attrs: AttributeSet) : View
7661
private var sweepAngle = 0f
7762

7863
//表盘中心文字
79-
private var centerText = "未定义"
80-
private lateinit var currentValuePaint: TextPaint
64+
private var centerText = "###"
8165
private lateinit var centerPaint: TextPaint
8266
private lateinit var forePaint: Paint
8367

@@ -88,33 +72,27 @@ class AirDashBoardView constructor(context: Context, attrs: AttributeSet) : View
8872
* getDimensionPixelSize()返回的是实际数值的四舍五入
8973
* getDimensionPixelOffset返回的是实际数值去掉后面的小数点
9074
*/
91-
ringRadius = type.getDimensionPixelOffset(
75+
ringRadius = type.getDimensionPixelSize(
9276
R.styleable.AirDashBoardView_air_ring_radius, 100.dp2px(context)
9377
)
94-
//需要给外围刻度留位置
95-
viewSideLength = ringRadius + 30.dp2px(context)
78+
viewSideLength = ringRadius + 15.dp2px(context)
9679
//辅助框
9780
viewRect = Rect(-viewSideLength, -viewSideLength, viewSideLength, viewSideLength)
9881
ringRectF = RectF(
9982
-ringRadius.toFloat(), -ringRadius.toFloat(), ringRadius.toFloat(), ringRadius.toFloat()
10083
)
10184
background = type.getColor(R.styleable.AirDashBoardView_air_ring_background, Color.LTGRAY)
102-
ringStroke = type.getDimensionPixelOffset(
85+
foreground = type.getColor(R.styleable.AirDashBoardView_air_ring_foreground, Color.BLUE)
86+
ringStroke = type.getDimensionPixelSize(
10387
R.styleable.AirDashBoardView_air_ring_stroke, 5.dp2px(context)
10488
)
10589

106-
thresholdTextSize = type.getDimensionPixelOffset(
107-
R.styleable.AirDashBoardView_air_valueSize, 12.dp2px(context)
90+
centerTextSize = type.getDimensionPixelSize(
91+
R.styleable.AirDashBoardView_air_center_text_size, 20.sp2px(context)
10892
)
109-
thresholdColor = type.getColor(R.styleable.AirDashBoardView_air_valueColor, Color.LTGRAY)
110-
111-
currentValueTextSize = type.getDimensionPixelOffset(
112-
R.styleable.AirDashBoardView_air_current_valueSize, 24.dp2px(context)
113-
)
114-
centerTextSize = type.getDimensionPixelOffset(
115-
R.styleable.AirDashBoardView_air_center_textSize, 12.dp2px(context)
93+
centerTextColor = type.getColor(
94+
R.styleable.AirDashBoardView_air_center_text_color, Color.BLUE
11695
)
117-
11896
type.recycle()
11997

12098
//初始化画笔
@@ -132,32 +110,29 @@ class AirDashBoardView constructor(context: Context, attrs: AttributeSet) : View
132110
ringPaint.color = background
133111
ringPaint.strokeCap = Paint.Cap.ROUND
134112
ringPaint.style = Paint.Style.STROKE
135-
ringPaint.strokeWidth = ringStroke.toFloat().dp2px(context)
113+
ringPaint.strokeWidth = ringStroke.toFloat()
136114
ringPaint.isAntiAlias = true
137-
//设置背景光晕
138-
ringPaint.maskFilter = BlurMaskFilter(15f, BlurMaskFilter.Blur.SOLID)
139115

140116
thresholdPaint = TextPaint()
141-
thresholdPaint.color = thresholdColor
117+
thresholdPaint.color = Color.DKGRAY
142118
thresholdPaint.isAntiAlias = true
143119
thresholdPaint.textAlign = Paint.Align.CENTER
144-
thresholdPaint.textSize = thresholdTextSize.toFloat()
145-
146-
currentValuePaint = TextPaint()
147-
currentValuePaint.isAntiAlias = true
148-
currentValuePaint.textAlign = Paint.Align.CENTER
149-
currentValuePaint.textSize = currentValueTextSize.toFloat()
120+
thresholdPaint.textSize = 16f.dp2px(context)
150121

151122
centerPaint = TextPaint()
123+
centerPaint.color = centerTextColor
152124
centerPaint.isAntiAlias = true
153125
centerPaint.textAlign = Paint.Align.CENTER
154126
centerPaint.textSize = centerTextSize.toFloat()
155127

156128
forePaint = Paint()
129+
forePaint.color = foreground
157130
forePaint.strokeCap = Paint.Cap.ROUND
158131
forePaint.style = Paint.Style.STROKE
159-
forePaint.strokeWidth = ringStroke.toFloat().dp2px(context)
132+
forePaint.strokeWidth = ringStroke.toFloat()
160133
forePaint.isAntiAlias = true
134+
//设置背景光晕
135+
forePaint.maskFilter = BlurMaskFilter(15f, BlurMaskFilter.Blur.SOLID)
161136
}
162137

163138
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
@@ -198,8 +173,8 @@ class AirDashBoardView constructor(context: Context, attrs: AttributeSet) : View
198173
* 画布移到中心位置,方便绘制一系列图形
199174
*/
200175
canvas.translate(centerX, centerY)
201-
202176
// drawGuides(canvas)
177+
203178
/**
204179
* 从左往右画,顺时针,左边是180度
205180
*/
@@ -296,83 +271,47 @@ class AirDashBoardView constructor(context: Context, attrs: AttributeSet) : View
296271
}
297272

298273
private fun drawMinValue(canvas: Canvas) {
299-
val fontMetrics = thresholdPaint.fontMetrics
300-
val top = fontMetrics.top
301-
val bottom = fontMetrics.bottom
302274
canvas.drawText(
303275
minValue.toString(),
304276
-viewSideLength / 2f,
305-
viewSideLength / 2f - (top + bottom) * 2.5f,
277+
viewSideLength / 2f + viewSideLength / 3f,
306278
thresholdPaint
307279
)
308280
}
309281

310282
private fun drawMaxValue(canvas: Canvas) {
311-
val fontMetrics = thresholdPaint.fontMetrics
312-
val top = fontMetrics.top
313-
val bottom = fontMetrics.bottom
314283
canvas.drawText(
315284
maxValue.toString(),
316285
viewSideLength / 2f,
317-
viewSideLength / 2f - (top + bottom) * 2.5f,
286+
viewSideLength / 2f + viewSideLength / 3f,
318287
thresholdPaint
319288
)
320289
}
321290

322291
private fun drawCurrentValue(canvas: Canvas) {
323-
val fontMetrics = currentValuePaint.fontMetrics
324-
val top = fontMetrics.top
325-
val bottom = fontMetrics.bottom
326292
canvas.drawText(
327293
currentValue.toString(),
328294
0f,
329-
-(top + bottom) / 2f,
330-
currentValuePaint
295+
viewSideLength / 2f - viewSideLength / 3f,
296+
centerPaint
331297
)
332298
}
333299

334300
private fun drawCenterText(canvas: Canvas) {
335-
val fontMetrics = centerPaint.fontMetrics
336-
val top = fontMetrics.top
337-
val bottom = fontMetrics.bottom
338301
canvas.drawText(
339302
centerText,
340303
0f,
341-
(top + bottom) * 2,
304+
-viewSideLength / 12f,
342305
centerPaint
343306
)
344307
}
345308

346-
fun setMaxValue(maxValue: Int): AirDashBoardView {
347-
this.maxValue = maxValue
348-
invalidate()
349-
return this
350-
}
351-
352309
fun setCenterText(centerText: String): AirDashBoardView {
353310
this.centerText = centerText
354311
invalidate()
355312
return this
356313
}
357314

358-
fun setAirRingForeground(@ColorInt color: Int): AirDashBoardView {
359-
forePaint.color = color
360-
invalidate()
361-
return this
362-
}
363-
364-
fun setAirCenterTextColor(@ColorInt color: Int): AirDashBoardView {
365-
centerPaint.color = color
366-
invalidate()
367-
return this
368-
}
369-
370-
fun setAirCurrentValueColor(@ColorInt color: Int): AirDashBoardView {
371-
currentValuePaint.color = color
372-
invalidate()
373-
return this
374-
}
375-
376315
fun setCurrentValue(value: Int) {
377316
currentValue = if (value < 0) {
378317
0
@@ -382,36 +321,18 @@ class AirDashBoardView constructor(context: Context, attrs: AttributeSet) : View
382321
value
383322
}
384323

385-
CoroutineScope(Dispatchers.Main).launch {
386-
withContext(Dispatchers.IO) {
387-
for (i in 0 until currentValue) {
388-
weakReferenceHandler.post(updateProgressRunnable.setProgress(i))
389-
delay(10)
324+
val i = intArrayOf(0)
325+
post(object : Runnable {
326+
override fun run() {
327+
i[0]++
328+
sweepAngle = i[0].toFloat() * 270 / maxValue
329+
invalidate()
330+
if (i[0] <= value) {
331+
postDelayed(this, 5)
332+
} else {
333+
removeCallbacks(this)
390334
}
391335
}
392-
}
393-
}
394-
395-
private interface UpdateProgressRunnable : Runnable {
396-
fun setProgress(progress: Int): UpdateProgressRunnable
397-
}
398-
399-
private val updateProgressRunnable = object : UpdateProgressRunnable {
400-
401-
private var progress = 0
402-
403-
override fun setProgress(progress: Int): UpdateProgressRunnable {
404-
this.progress = progress
405-
return this
406-
}
407-
408-
override fun run() {
409-
sweepAngle = progress.toFloat() * 270 / maxValue
410-
invalidate()
411-
}
412-
}
413-
414-
override fun handleMessage(msg: Message): Boolean {
415-
return true
336+
})
416337
}
417338
}

lite/src/main/res/values/attrs.xml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,11 @@
1717
<declare-styleable name="AirDashBoardView">
1818
<attr name="air_ring_radius" format="dimension" />
1919
<attr name="air_ring_background" format="color" />
20+
<attr name="air_ring_foreground" format="color" />
2021
<attr name="air_ring_stroke" format="dimension" />
2122

22-
<attr name="air_valueColor" format="color" />
23-
<attr name="air_valueSize" format="dimension" />
24-
25-
<attr name="air_current_valueColor" format="color" />
26-
<attr name="air_current_valueSize" format="dimension" />
27-
28-
<attr name="air_center_textSize" format="dimension" />
29-
<attr name="air_center_textColor" format="color" />
23+
<attr name="air_center_text_size" format="dimension" />
24+
<attr name="air_center_text_color" format="color" />
3025
</declare-styleable>
3126

3227
<declare-styleable name="SlideBarView">

0 commit comments

Comments
 (0)