我希望能够使用绘图在画布上将一些文字(例如数量,最大可以为7个数字长(1000000))放在一个圆圈内。问题是,在某些设备屏幕上,文本超出了下面的圆的直径,我粘贴了用文本绘制自定义圆的代码。
到目前为止,代码我还可以在其中绘制圆和文本。该代码可以使用938之类的小数字,但是如果某些设备上的数字超过5个或更多,它将超出直径范围。
class CircularProgressBar @JvmOverloads constructor(context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0) : View(context,attrs,defStyleAttr) {
private var mViewWidth: Int = 0
private var mViewHeight: Int = 0
private val mStartAngle = -90f
private var mSweepAngle = 0f
private val mMaxSweepAngle = 360f
private var mStrokeWidth = 20
private val mAnimationDuration = 400
private val mMaxProgress = 100
private var mDrawText = true
private var amount:String? = null
private var currency:String? = null
private var mProgressColor = Color.BLACK
private var mTextColor = Color.BLACK
private val mPaint: Paint = Paint(Paint.ANTI_ALIAS_flaG)
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
initMeasurements()
drawBackGroundArch(canvas)
drawOutlineArc(canvas)
if (mDrawText) {
drawPercentageText(canvas)
drawAmountText(canvas)
}
}
private fun initMeasurements() {
mViewWidth = width
mViewHeight = height
}
private fun drawOutlineArc(canvas: Canvas) {
val diameter = min(mViewWidth,mViewHeight) - (mStrokeWidth -25)* 2
val outerOval = RectF(
mStrokeWidth.toFloat(),mStrokeWidth.toFloat(),diameter.toFloat(),diameter.toFloat()
)
mPaint.color = mProgressColor
mPaint.strokeWidth = mStrokeWidth.toFloat()
mPaint.isAntiAlias = true
mPaint.strokeCap = Paint.Cap.ROUND
mPaint.style = Paint.Style.STROKE
canvas.drawArc(outerOval,mStartAngle,mSweepAngle,false,mPaint)
}
private fun drawBackGroundArch(canvas: Canvas) {
val diameter = min(mViewWidth,mViewHeight) - (mStrokeWidth -25) * 2
val outerOval = RectF(
mStrokeWidth.toFloat(),diameter.toFloat()
)
mPaint.color = Color.LTGRAY
mPaint.strokeWidth = mStrokeWidth.toFloat()
mPaint.isAntiAlias = true
mPaint.strokeCap = Paint.Cap.ROUND
mPaint.style = Paint.Style.STROKE
canvas.drawArc(outerOval,mMaxSweepAngle,mPaint)
}
private fun drawPercentageText(canvas: Canvas) {
mPaint.textSize = mViewWidth.coerceAtMost(mViewHeight) / 7f
mPaint.textAlign = Paint.Align.CENTER
mPaint.strokeWidth = 0f
mPaint.color = mTextColor
// Center text
val xPos = canvas.width / 2
val yPos = (canvas.height / 2 - (mPaint.descent() + mPaint.ascent()) / 2).toInt() - 60
canvas.drawText(
calcProgressFromSweepAngle(mSweepAngle).toString() + "%",xPos.toFloat(),yPos.toFloat(),mPaint
)
}
private fun drawAmountText(canvas: Canvas) {
mPaint.textSize = mViewWidth.coerceAtMost(mViewHeight) / 11f
mPaint.textAlign = Paint.Align.CENTER
mPaint.strokeWidth = 0f
mPaint.color = mTextColor
// Center text
val xPos = canvas.width / 2
val yPos = (canvas.height / 2 - (mPaint.descent() + mPaint.ascent()) / 2).toInt() + 40
canvas.drawText(amount + " " + currency,mPaint
)
}
private fun calcSweepAngleFromProgress(progress: Int): Float {
return mMaxSweepAngle / mMaxProgress * progress
}
private fun calcProgressFromSweepAngle(sweepAngle: Float): Int {
return (sweepAngle * mMaxProgress / mMaxSweepAngle).toInt()
}
fun setProgress(progress: Int) {
val animator = ValueAnimator.ofFloat(mSweepAngle,calcSweepAngleFromProgress(progress))
animator.interpolator = DecelerateInterpolator()
animator.duration = mAnimationDuration.toLong()
animator.addUpdateListener { valueAnimator ->
mSweepAngle = valueAnimator.animatedValue as Float
invalidate()
}
animator.start()
}
fun setProgressColor(color: Int) {
mProgressColor = color
invalidate()
}
fun setProgressWidth(width: Int) {
mStrokeWidth = width
invalidate()
}
fun setamountText(amount:String){
this.amount = amount
invalidate()
}
fun setCurrencyType(currency:String){
this.currency = currency
}
fun setTextColor(color: Int) {
mTextColor = color
invalidate()
}
}
我正在寻找的解决方案是不允许文本超出圆直径。