Мне нужен собственный индикатор выполнения для проекта, и я смог нарисовать его, но я застрял с выравниванием текста внутри индикатора выполнения
class DashedCircularProgress : View {
private val START_ANGLE = -90
private lateinit var circleBounds: RectF
private var mLayoutHeight = 0
private var mLayoutWidth = 0
private var STROKE_WIDTH = 20.0f
var progressValue = 15f
val airPollution: String = "AIR POLLUTION"
private lateinit var paint: Paint
private lateinit var textPaint: Paint
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
init(attrs, 0)
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
init(attrs, defStyleAttr)
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(
context,
attrs,
defStyleAttr,
defStyleRes
) {
init(attrs, defStyleRes)
}
private fun init(attrs: AttributeSet, defStyleRes: Int) {
val ta = context.obtainStyledAttributes(
attrs,
R.styleable.DashedCircularProgress, defStyleRes, 0
)
progressValue =
ta.getFloat(
R.styleable.DashedCircularProgress_dcp_progress,
progressValue
)
paint = Paint(Paint.ANTI_ALIAS_FLAG)
val dashPath = DashPathEffect(floatArrayOf(100f, 5f), 5.0.toFloat())
paint.color = getRandomColor()
// paint.setPathEffect(dashPath)
paint.style = Paint.Style.STROKE
paint.strokeWidth = 35f
ta.recycle()
}
private fun getRandomColor(): Int {
val rnd = Random()
val color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256))
return color
}
override fun onSizeChanged(newWidth: Int, newHeight: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(newWidth, newHeight, oldw, oldh)
mLayoutWidth = newWidth
mLayoutHeight = newHeight
setupBounds()
}
private fun setupBounds() {
val minValue = Math.min(mLayoutWidth, mLayoutHeight)
val xOffset = mLayoutWidth - minValue
val yOffset = mLayoutHeight - minValue
val paddingTop = this.paddingTop + yOffset / 2
val paddingBottom = this.paddingBottom + yOffset / 2
val paddingLeft = this.paddingLeft + xOffset / 2
val paddingRight = this.paddingRight + xOffset / 2
val width = width
val height = height
circleBounds = RectF(
paddingLeft.toFloat() + STROKE_WIDTH * 2,
paddingTop.toFloat() + STROKE_WIDTH * 2,
mLayoutWidth.toFloat() - STROKE_WIDTH * 2 - paddingRight,
mLayoutHeight.toFloat() - STROKE_WIDTH * 2 - paddingBottom
)
textPaint = Paint(Paint.ANTI_ALIAS_FLAG)
textPaint.textSize = 42f
textPaint.color = Color.BLUE
/* val textWidth = textPaint.measureText(airPollution)
if (circleBounds.width() /2< textWidth) {
Handler().postDelayed({
textPaint.textSize = 18f
invalidate()
}, 5000)
}*/
// textPaint.getTextBounds(airPollution,0,airPollution.length,circleBounds.toRect())
Log.d("Values", "circleBounds")
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val degree = 90
val progressAngle = getProgressAngle(progressValue)
for (i in 0 until (progressAngle / 90f).toInt() + 1) {
paint.color = getColorForIndex(i)
var progressToLoad = 90f
val degreeValue = (degree * i)
if (i == (progressAngle / 90).toInt()) {
progressToLoad = (progressAngle - degreeValue)
for (j in 0 until (progressToLoad / 22.5).toInt()) {
canvas.drawArc(
circleBounds,
(START_ANGLE + degreeValue).toFloat() + (22 * j),
if (j == 3) 22f else 20f,
false,
paint
)
}
} else {
for (k in 0 until 4 step 1) {
canvas.drawArc(
circleBounds,
(START_ANGLE + degreeValue).toFloat() + (22 * k),
if (k == 3) 22f else 20f,
false,
paint
)
}
}
// canvas.drawText(progressValue.toString(),(circleBounds.width()/2),(circleBounds.height()/2),paint)
//canvas.drawText("AIR POLLUTION",0f,0f ,textPaint)
canvas.drawText(
"AIR POLLUTION",
circleBounds.width() / 2,
circleBounds.height() / 2,
textPaint
)
}
}
private fun getProgressAngle(percent: Float): Float {
return percent / 100.toFloat() * 360
}
fun setProgress(progressValue: Float) {
this.progressValue = progressValue
invalidate()
}
private fun getColorForIndex(index: Int): Int {
when (index) {
0 -> {
return Color.RED
}
1 -> {
return Color.YELLOW
}
2 -> {
return Color.GREEN
}
3 -> {
return Color.BLUE
}
else -> return Color.MAGENTA
}
}
}
Здесь текст касается индикатора выполнения, в этом случае мне нужно изменить размер текста до меньшего значения. Это то, что я пытался решить, и я не уверен, что это хороший подход к этому
val textWidth = textPaint.measureText(airPollution)
if (circleBounds.width() /2< textWidth) {
textPaint.textSize = 18f
invalidate()
}