WeightView.kt 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package com.develop.common.widget
  2. import android.content.Context
  3. import android.graphics.Canvas
  4. import android.graphics.Color
  5. import android.graphics.Paint
  6. import android.graphics.Path
  7. import android.text.TextPaint
  8. import android.util.AttributeSet
  9. import android.util.TypedValue
  10. import android.view.View
  11. import android.widget.Scroller
  12. import com.develop.base.ext.dimenRes
  13. import com.develop.base.R
  14. import com.develop.base.ext.getSN
  15. import com.develop.base.ext.isBrand062
  16. class WeightView @JvmOverloads constructor(
  17. context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
  18. ) : View(context, attrs, defStyleAttr) {
  19. private val path = Path()
  20. private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
  21. private val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
  22. private val outlineStrokeWidth = dimenRes(com.develop.common.R.dimen.convert_9px).toFloat()
  23. private val scaleStrokeWidth = dimenRes(com.develop.common.R.dimen.convert_4px).toFloat()
  24. private val scaleTopPosition = dimenRes(com.develop.common.R.dimen.convert_20px).toFloat()
  25. private val scaleBtmPosition = dimenRes(com.develop.common.R.dimen.convert_50px).toFloat()
  26. private val textPutPosition = dimenRes(com.develop.common.R.dimen.convert_90px).toFloat()
  27. private val triangleWidth = dimenRes(com.develop.common.R.dimen.convert_60px).toFloat()
  28. private val triangleHeight = dimenRes(com.develop.common.R.dimen.convert_30px).toFloat()
  29. private val triangleMargin = dimenRes(com.develop.common.R.dimen.convert_3px).toFloat()
  30. private var rotateOffset = 0f
  31. private val scroller = Scroller(context)
  32. private val gapCount = 20
  33. private val is062 = isBrand062()
  34. private val sn = getSN()
  35. init {
  36. paint.strokeWidth = outlineStrokeWidth
  37. textPaint.textSize = TypedValue.applyDimension(
  38. TypedValue.COMPLEX_UNIT_DIP,
  39. 14f, context.resources.displayMetrics
  40. )
  41. textPaint.color = Color.WHITE
  42. }
  43. override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
  44. super.onMeasure(widthMeasureSpec, heightMeasureSpec)
  45. val width = MeasureSpec.getSize(widthMeasureSpec)
  46. setMeasuredDimension(width, width / 2)
  47. }
  48. override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
  49. super.onSizeChanged(w, h, oldw, oldh)
  50. val triangleBottomY = width * 0.25f - triangleMargin - outlineStrokeWidth / 2f
  51. path.reset()
  52. path.moveTo(width / 2f - triangleWidth / 2, triangleBottomY)
  53. path.lineTo(width / 2f, triangleBottomY - triangleHeight)
  54. path.lineTo(width / 2f + triangleWidth / 2, triangleBottomY)
  55. path.close()
  56. }
  57. override fun onDraw(canvas: Canvas) {
  58. super.onDraw(canvas)
  59. paint.color = if (is062) 0xffDAE343.toInt()
  60. else if (sn.startsWith("011F")) 0xff60F262.toInt()
  61. else 0xffe60012.toInt() // 三角形指示器
  62. canvas.drawPath(path, paint)
  63. paint.style = Paint.Style.STROKE
  64. paint.strokeWidth = outlineStrokeWidth
  65. paint.color = Color.WHITE
  66. canvas.drawCircle(width / 2f, height.toFloat(), width / 2f - outlineStrokeWidth / 2f, paint)
  67. paint.color = Color.parseColor("#99ffffff")
  68. canvas.drawCircle(width / 2f, height.toFloat(), width * 0.25f, paint)
  69. paint.strokeWidth = scaleStrokeWidth
  70. paint.color = Color.WHITE
  71. val intervalDegree = 360 / gapCount
  72. canvas.save()
  73. canvas.rotate(-rotateOffset % 360, width / 2f, height.toFloat())
  74. repeat(gapCount) {
  75. canvas.drawLine(width / 2f, scaleTopPosition, width / 2f, scaleBtmPosition, paint)
  76. val scaleText = getWeightNumber(it)
  77. val textWidth = textPaint.measureText(scaleText)
  78. canvas.drawText(scaleText, width / 2f - textWidth / 2, textPutPosition, textPaint)
  79. canvas.rotate(intervalDegree.toFloat(), width / 2f, height.toFloat())
  80. }
  81. canvas.restore()
  82. }
  83. override fun computeScroll() {
  84. super.computeScroll()
  85. if (!scroller.computeScrollOffset()) {
  86. return
  87. }
  88. rotateOffset = scroller.currX.toFloat()
  89. invalidate()
  90. }
  91. private fun getWeightNumber(index: Int): String {
  92. if (rotateOffset <= 90 && index >= 14 && index <= 19) {
  93. // 特殊处理0左边的值
  94. return ((index + 1) * 250).toString()
  95. }
  96. val loopIndex = (((rotateOffset - 270f) / 360f) + 1).toInt()
  97. val accumulate = 200 * loopIndex + index * 10
  98. if (loopIndex >= 1) {
  99. val borderValue = (loopIndex - 1) * 360 + 540
  100. if (index <= 10 || rotateOffset >= borderValue) {
  101. return accumulate.toString()
  102. } else {
  103. return (accumulate - 200).toString()
  104. }
  105. }
  106. return (index * 10).toString()
  107. }
  108. fun setWeightNumber(weight: Float) {
  109. val dDegree = getDegreeByWeight(weight) - rotateOffset
  110. if (dDegree.compareTo(0) == 0) {
  111. return
  112. }
  113. scroller.abortAnimation()
  114. scroller.startScroll(
  115. rotateOffset.toInt(), 0,
  116. dDegree.toInt(), 0,
  117. 300
  118. )
  119. invalidate()
  120. }
  121. private fun getDegreeByWeight(weight: Float): Float {
  122. return weight / 10f * 18f
  123. }
  124. }