android——角标

效果图:

自定义角标控件:

package com.example.mytest.widget

import android.content.Context
import android.graphics.Color
import android.graphics.RectF
import android.graphics.Typeface
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RoundRectShape
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateInterpolator
import android.view.animation.AlphaAnimation
import android.view.animation.Animation
import android.view.animation.DecelerateInterpolator
import android.widget.FrameLayout
import android.widget.TabWidget

class BadgeView @JvmOverloads constructor(
    context: Context?,
    attrs: AttributeSet? = null,
    defStyle: Int = 16842884,
    target: View? = null,
    tabIndex: Int = 0
) :
    androidx.appcompat.widget.AppCompatTextView(context!!, attrs, defStyle) {
    private var context: Context? = null
    var target: View? = null
        private set
    var badgePosition = 0
    var horizontalBadgeMargin = 0
        private set
    var verticalBadgeMargin = 0
        private set
    private var badgeColor = 0
    private var isShown = false
    private var badgeBg: ShapeDrawable? = null
    private var targetTabIndex = 0

    constructor(context: Context?, target: View?) : this(
        context,
        null as AttributeSet?,
        16842884,
        target,
        0
    ) {
    }

    constructor(context: Context?, target: TabWidget?, index: Int) : this(
        context,
        null as AttributeSet?,
        16842884,
        target,
        index
    ) {
    }

    init {
        init(context, target, tabIndex)
    }

    private fun init(context: Context?, target: View?, tabIndex: Int) {
        this.context = context
        this.target = target
        targetTabIndex = tabIndex
        badgePosition = 2
        horizontalBadgeMargin = dipToPixels(5)
        verticalBadgeMargin = horizontalBadgeMargin
        badgeColor = DEFAULT_BADGE_COLOR
        this.typeface = Typeface.DEFAULT_BOLD
        val paddingPixels = dipToPixels(5)
        setPadding(paddingPixels, 0, paddingPixels, 0)
        this.setTextColor(-1)
        fadeIn = AlphaAnimation(0.0f, 1.0f)
        fadeIn!!.setInterpolator(DecelerateInterpolator())
        fadeIn!!.setDuration(200L)
        fadeOut = AlphaAnimation(1.0f, 0.0f)
        fadeOut!!.setInterpolator(AccelerateInterpolator())
        fadeOut!!.setDuration(200L)
        isShown = false
        if (this.target != null) {
            applyTo(this.target)
        } else {
            this.show()
        }
    }

    private fun applyTo(target: View?) {
        var target = target
        val lp = target!!.layoutParams
        val parent = target.parent
        val container = FrameLayout(context!!)
        if (target is TabWidget) {
            target = target.getChildTabViewAt(targetTabIndex)
            this.target = target
            (target as ViewGroup?)!!.addView(container, ViewGroup.LayoutParams(-1, -1))
            this.visibility = GONE
            container.addView(this)
        } else {
            val group = parent as ViewGroup
            val index = group.indexOfChild(target)
            group.removeView(target)
            group.addView(container, index, lp)
            container.addView(target)
            this.visibility = GONE
            container.addView(this)
            group.invalidate()
        }
    }

    fun show() {
        this.show(false, null as Animation?)
    }

    fun show(animate: Boolean) {
        this.show(animate, fadeIn)
    }

    fun show(anim: Animation?) {
        this.show(true, anim)
    }

    fun hide() {
        this.hide(false, null as Animation?)
    }

    fun hide(animate: Boolean) {
        this.hide(animate, fadeOut)
    }

    fun hide(anim: Animation?) {
        this.hide(true, anim)
    }

    fun toggle() {
        this.toggle(false, null as Animation?, null as Animation?)
    }

    fun toggle(animate: Boolean) {
        this.toggle(animate, fadeIn, fadeOut)
    }

    fun toggle(animIn: Animation?, animOut: Animation?) {
        this.toggle(true, animIn, animOut)
    }

    private fun show(animate: Boolean, anim: Animation?) {
        if (this.background == null) {
            if (badgeBg == null) {
                badgeBg = defaultBackground
            }
            setBackgroundDrawable(badgeBg)
        }
        applyLayoutParams()
        if (animate) {
            startAnimation(anim)
        }
        this.visibility = VISIBLE
        isShown = true
    }

    private fun hide(animate: Boolean, anim: Animation?) {
        this.visibility = GONE
        if (animate) {
            startAnimation(anim)
        }
        isShown = false
    }

    private fun toggle(animate: Boolean, animIn: Animation?, animOut: Animation?) {
        if (isShown) {
            this.hide(animate && animOut != null, animOut)
        } else {
            this.show(animate && animIn != null, animIn)
        }
    }

    fun increment(offset: Int): Int {
        val txt = this.text
        var i: Int
        i = if (txt != null) {
            try {
                txt.toString().toInt()
            } catch (var5: NumberFormatException) {
                0
            }
        } else {
            0
        }
        i += offset
        this.text = i.toString()
        return i
    }

    fun decrement(offset: Int): Int {
        return increment(-offset)
    }

    private val defaultBackground: ShapeDrawable
        private get() {
            val r = dipToPixels(8)
            val outerR = floatArrayOf(
                r.toFloat(),
                r.toFloat(),
                r.toFloat(),
                r.toFloat(),
                r.toFloat(),
                r.toFloat(),
                r.toFloat(),
                r.toFloat()
            )
            val rr = RoundRectShape(outerR, null as RectF?, null as FloatArray?)
            val drawable = ShapeDrawable(rr)
            drawable.paint.color = badgeColor
            return drawable
        }

    private fun applyLayoutParams() {
        val lp = FrameLayout.LayoutParams(-2, -2)
        when (badgePosition) {
            1 -> {
                lp.gravity = 51
                lp.setMargins(horizontalBadgeMargin, verticalBadgeMargin, 0, 0)
            }
            2 -> {
                lp.gravity = 53
                lp.setMargins(0, verticalBadgeMargin, horizontalBadgeMargin, 0)
            }
            3 -> {
                lp.gravity = 83
                lp.setMargins(horizontalBadgeMargin, 0, 0, verticalBadgeMargin)
            }
            4 -> {
                lp.gravity = 85
                lp.setMargins(0, 0, horizontalBadgeMargin, verticalBadgeMargin)
            }
            5 -> {
                lp.gravity = 17
                lp.setMargins(0, 0, 0, 0)
            }
        }
        this.layoutParams = lp
    }

    override fun isShown(): Boolean {
        return isShown
    }

    fun setBadgeMargin(badgeMargin: Int) {
        horizontalBadgeMargin = badgeMargin
        verticalBadgeMargin = badgeMargin
    }

    fun setBadgeMargin(horizontal: Int, vertical: Int) {
        horizontalBadgeMargin = horizontal
        verticalBadgeMargin = vertical
    }

    var badgeBackgroundColor: Int
        get() = badgeColor
        set(badgeColor) {
            this.badgeColor = badgeColor
            badgeBg = defaultBackground
        }

    private fun dipToPixels(dip: Int): Int {
        val r = this.resources
        val px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip.toFloat(), r.displayMetrics)
        return px.toInt()
    }

    companion object {
        const val POSITION_TOP_LEFT = 1
        const val POSITION_TOP_RIGHT = 2
        const val POSITION_BOTTOM_LEFT = 3
        const val POSITION_BOTTOM_RIGHT = 4
        const val POSITION_CENTER = 5
        private const val DEFAULT_MARGIN_DIP = 5
        private const val DEFAULT_LR_PADDING_DIP = 5
        private const val DEFAULT_CORNER_RADIUS_DIP = 8
        private const val DEFAULT_POSITION = 2
        private val DEFAULT_BADGE_COLOR = Color.parseColor("#CCFF0000")
        private const val DEFAULT_TEXT_COLOR = -1
        private var fadeIn: AlphaAnimation? = null
//        private var fadeOut: Animation? = null
        private var fadeOut: AlphaAnimation? = null
    }
}

使用:

val btff = findViewById<TextView>(R.id.bt_ff) // 添加在TextView右上角
        var badge = BadgeView(this, btff)
        badge.text = "12"
        //设置文本颜色
//        badge.setTextColor(Color.WHITE)
//        //设置背景颜色
//        badge.badgeBackgroundColor = Color.RED
//        //显示
        badge.show()

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wy313622821

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值