自定义TextView open class TagTextView @JvmOverloads constructor

只要在自定义控件的onDraw()中先绘制背景再绘制消息数即可,自定义控件完整代码如下:
//'自定义TextView'
open class TagTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : AppCompatTextView(context, attrs, defStyleAttr) {
    //'消息数字体大小'
    var tagTextSize: Float = 0F
        set(value) {
            field = value
            textPaint.textSize = value
        }
    //'消息数字体颜色'
    var tagTextColor: Int = Color.parseColor("#FFFFFF")
        set(value) {
            field = value
            textPaint.color = value
        }
    //'背景色'
    var tagBgColor: Int = Color.parseColor("#FFFF5183")
        set(value) {
            field = value
            bgPaint.color = value
        }
    //'消息数字体'
    var tagTextTypeFace: Typeface? = null

    //'消息数'
    var tagText: String? = null
    //'背景和消息数的间距'
    var tagTextPaddingTop: Float = 5f
    var tagTextPaddingBottom: Float = 5f
    var tagTextPaddingStart: Float = 5f
    var tagTextPaddingEnd: Float = 5f
    
    //'消息数字体区域'
    private var textRect: Rect = Rect()
    //'消息数画笔'
    private var textPaint: Paint = Paint()
    //'背景画笔'
    private var bgPaint: Paint = Paint()

    init {
        //'构建消息数画笔'
        textPaint.apply {
            color = tagTextColor
            textSize = tagTextSize
            isAntiAlias = true
            textAlign = Paint.Align.CENTER
            style = Paint.Style.FILL
            tagTextTypeFace?.let { typeface = tagTextTypeFace }
        }
        //'构建背景画笔'
        bgPaint.apply {
            isAntiAlias = true
            style = Paint.Style.FILL
            color = tagBgColor
        }
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        //'只有当消息数不为空时才绘制小红点'
        tagText?.takeIf { it.isNotEmpty() }?.let { text ->
            textPaint.apply {
                //'1.获取消息数区域大小'
                getTextBounds(text, 0, text.length, textRect)
                fontMetricsInt.let {
                    //'背景宽=消息数区域宽+边距'
                    val bgWidth = (textRect.right - textRect.left) + tagTextPaddingStart + tagTextPaddingEnd
                    //'背景高=消息数区域高+边距'
                    val bgHeight = tagTextPaddingBottom + tagTextPaddingTop + it.bottom - it.top
                    //'取宽高中的较大值作为半径'
                    val radius = if (bgWidth > bgHeight) bgWidth / 2 else bgHeight / 2
                    val centerX = width - radius
                    val centerY = radius
                    //'2.绘制背景'
                    canvas?.drawCircle(centerX, centerY, radius, bgPaint)
                    //'3.绘制基线'
                    val baseline = radius + (it.bottom - it.top) / 2 - it.bottom
                    canvas?.drawText(text, width - radius, baseline, textPaint)
                }
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值