private val SPORT_RADIUS = 150.dp
class SportView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
private val text = "aaaa"
//存储文字边界
private val bounds = Rect()
private val fontMetrics = Paint.FontMetrics()
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
//绘制圆环
mPaint.color = Color.GRAY
mPaint.style = Paint.Style.STROKE
mPaint.strokeWidth = 20.dp
canvas.drawCircle((width/2).toFloat(), (height/2).toFloat(),SPORT_RADIUS,mPaint)
//绘制进度条
mPaint.color = Color.GREEN
mPaint.strokeCap = Paint.Cap.ROUND
canvas.drawArc(width/2- SPORT_RADIUS,height/2- SPORT_RADIUS,width/2+ SPORT_RADIUS,height/2+ SPORT_RADIUS,-90f,225f,false,mPaint)
//绘制文字
mPaint.style = Paint.Style.FILL
mPaint.textSize = 100.dp
//设置文字左右居中
mPaint.textAlign = Paint.Align.CENTER
//文字默认会在纵向基准线baseline的上方
// mPaint.getTextBounds(text,0,text.length,bounds)
// Log.d("SportView",bounds.toString())
//适用于静态的文字居中效果
// val centerY = height/2f-(bounds.top+bounds.bottom)/2
//ascent 文字核心部分的顶部
// descent 文字核心部分的底部
// top bottom 文字顶部和底部的极限值
//动态文字居中策略,为了防止文字跳动
mPaint.getFontMetrics(fontMetrics)
//核心部分居中
val centerY = height/2f - (mPaint.ascent()+mPaint.descent())/2
canvas.drawText(text,width/2f,centerY,mPaint)
}
}
总结
静态的文字居中效果 使用height/2f-(bounds.top+bounds.bottom)/2动态文字居中策略,为了防止文字跳动 使用 height/2f - (mPaint.ascent()+mPaint.descent())/2