kotlin代码编写
- 可以设置只展示红点
- 数量为0时隐藏此view
- 数量为0-9时是原形红点
- 数量大于9 小于等于99时展示具体数量
- 数量为大于99时显示···
- 可以自己设置外圈圆环,及其颜色。
view代码
package com.k.android.view
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import com.k.android.R
import com.k.android.view.calendar.Utils
class RedDotView(context: Context, attr: AttributeSet) : View(context,attr) {
private val threeDot:String="···"
private var attrBean = DotViewAttr(context,attr)
private var mOnlyDot:Boolean=false
private var mText:Int=0
private var paint = Paint()//画笔
private val rect= Rect()//计算文字宽高的矩形
private var textWidth = 0
private var textHeight = 0
private var viewWidth = 0
private var viewHeight = 0
private val ringWidth = 4
override fun draw(canvas: Canvas?) {
super.draw(canvas)
paint.isAntiAlias=true//设置抗锯齿
if(mOnlyDot){//只画一个圆点 半径的一半为中心点
paint.color = attrBean.dotColor
if(attrBean.dotShowRing){
paint.color=attrBean.dotRingColor
canvas?.drawCircle(viewWidth.toFloat()/2,viewHeight.toFloat()/2,attrBean.dotDiameter.toFloat()/2,paint)
paint.color=attrBean.dotColor
canvas?.drawCircle(viewWidth.toFloat()/2,viewHeight.toFloat()/2,attrBean.dotDiameter.toFloat()/2-ringWidth,paint)
}else{
paint.color=attrBean.dotColor
canvas?.drawCircle(viewWidth.toFloat()/2,viewHeight.toFloat()/2,attrBean.dotDiameter.toFloat()/2,paint)
}
}else{
if(mText==0){//等于0不显示此view所以不执行任何代码
visibility = GONE
return
}
if(mText in 1..9){//画圆
//画圆
if(attrBean.dotShowRing){
paint.color=attrBean.dotRingColor
canvas?.drawCircle(viewWidth.toFloat()/2,viewHeight.toFloat()/2,viewHeight.toFloat()/2,paint)
paint.color=attrBean.dotColor
canvas?.drawCircle(viewWidth.toFloat()/2,viewHeight.toFloat()/2,viewHeight.toFloat()/2-ringWidth,paint)
}else{
paint.color=attrBean.dotColor
canvas?.drawCircle(viewWidth.toFloat()/2,viewHeight.toFloat()/2,viewHeight.toFloat()/2,paint)
}
//写字
paint.color = attrBean.dotTextColor
paint.textSize = attrBean.dotTextSize.toFloat()
canvas?.drawText(mText.toString(),(viewWidth-textWidth).toFloat()/2-1,(viewHeight+textHeight).toFloat()/2-1,paint)
}else{//画圆角矩形
//计算文字宽高
//画圆角矩形
if(attrBean.dotShowRing){
paint.color = attrBean.dotRingColor
val oval = RectF(0f, 0f, viewWidth.toFloat(), viewHeight.toFloat())// 设置个新的长方形
canvas?.drawRoundRect(oval, viewHeight.toFloat()/2, viewHeight.toFloat()/2, paint)//第二个参数是x半径,第三个参数是y半径
paint.color = attrBean.dotColor
val oval2 = RectF(ringWidth.toFloat(), ringWidth.toFloat(), viewWidth.toFloat()-ringWidth, viewHeight.toFloat()-ringWidth)// 设置个新的长方形
canvas?.drawRoundRect(oval2, viewHeight.toFloat()/2-ringWidth, viewHeight.toFloat()/2-ringWidth, paint)//第二个参数是x半径,第三个参数是y半径
}else{
paint.color = attrBean.dotColor
val oval = RectF(0f, 0f, viewWidth.toFloat(), viewHeight.toFloat())// 设置个新的长方形
canvas?.drawRoundRect(oval, viewHeight.toFloat()/2, viewHeight.toFloat()/2, paint)//第二个参数是x半径,第三个参数是y半径
}
//写字
paint.color = attrBean.dotTextColor
paint.textSize = attrBean.dotTextSize.toFloat()
if(mText>99){
canvas?.drawText(threeDot,(viewWidth-textWidth).toFloat()/2-5,(viewHeight+textHeight).toFloat()/2+6,paint)
}else{
canvas?.drawText(mText.toString(),(viewWidth-textWidth).toFloat()/2-1,(viewHeight+textHeight).toFloat()/2-1,paint)
}
}
}
}
fun setText(text:Int){
if (text==0){
visibility = GONE
}else{
visibility = VISIBLE
}
mText = text
initWidthAHeight()
setOnlyDotMode(false)//设置数量时让只是红点模式为false
invalidate()
}
private fun initWidthAHeight(){
paint.textSize = attrBean.dotTextSize.toFloat()
if(mText>99){
paint.getTextBounds(threeDot,0,threeDot.length,rect)
}else{
paint.getTextBounds(mText.toString(),0,"$mText".length,rect)
}
textWidth = rect.width()
textHeight = rect.height()
if(mText >9){
viewWidth = attrBean.dotHeight+textWidth
}else if(mText in 1..9){
viewWidth = attrBean.dotHeight
}
viewHeight = attrBean.dotHeight
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
initParams()
}
fun setOnlyDotMode(onlyDot:Boolean){
mOnlyDot = onlyDot
initParams()
invalidate()
}
/**
* 默认,
*/
fun setOffset(view:View){
view.viewTreeObserver.addOnGlobalLayoutListener {
var x=0
var y=0
if (mOnlyDot){
x=Utils.dpi2px(context,-5f)
y=Utils.dpi2px(context,5f)
}else{
x=Utils.dpi2px(context,-6f)
y=Utils.dpi2px(context,7f)
}
setX(view.right.toFloat()-viewWidth/2+x)
setY(view.top.toFloat()-viewHeight/2+y)
}
}
//特殊定制,首页底部消息显示红点需要
fun setOffset(view:View,x:Int,y:Int,x1:Int,y1:Int){
view.viewTreeObserver.addOnGlobalLayoutListener {
var w=0
var h=0
if (mOnlyDot){
w=Utils.dpi2px(context,x.toFloat())
h=Utils.dpi2px(context,y.toFloat())
}else{
w=Utils.dpi2px(context,x1.toFloat())
h=Utils.dpi2px(context,y1.toFloat())
}
setX(view.right.toFloat()-viewWidth/2+w)
setY(view.top.toFloat()-viewHeight/2+h)
}
}
private fun initParams(){
if(mOnlyDot){
visibility = VISIBLE
layoutParams.width = attrBean.dotDiameter
layoutParams.height = attrBean.dotDiameter
viewHeight = attrBean.dotDiameter
viewWidth = attrBean.dotDiameter
}else{
if(mText >9){
layoutParams.width = attrBean.dotHeight+textWidth
layoutParams.height = attrBean.dotHeight
}else{
layoutParams.width = attrBean.dotHeight
layoutParams.height = attrBean.dotHeight
}
}
requestLayout()
}
}
class DotViewAttr(context:Context,attrs:AttributeSet){
val dotColor: Int //绘制的圆圈颜色
val dotTextSize: Int //绘制的文本颜色
val dotHeight: Int //绘制的圆环view高度 ,因为宽度是自适应的,所以不需要写
var dotDiameter:Int=0 //当只显示小红点时绘制的点的直径
val dotTextColor: Int //绘制的文本的颜色
val dotShowRing:Boolean //当需要外部显示边时,设置此项为true
val dotRingColor:Int//要显示边的颜色
init {
val ta = context.obtainStyledAttributes(attrs, R.styleable.RedDotView)
dotColor = ta.getColor(R.styleable.RedDotView_dotColor,Color.RED)
dotTextSize = ta.getDimensionPixelSize(R.styleable.RedDotView_dotTextSize, 15)
dotDiameter = ta.getDimensionPixelSize(R.styleable.RedDotView_dotDiameter, 10)
dotHeight = ta.getDimensionPixelSize(R.styleable.RedDotView_dotHeight, 10)
dotTextColor = ta.getColor(R.styleable.RedDotView_dotTextColor, Color.WHITE)
dotRingColor = ta.getColor(R.styleable.RedDotView_dotRingColor, Color.WHITE)
dotShowRing = ta.getBoolean(R.styleable.RedDotView_dotShowRing,false)
ta.recycle()
}
}
属性代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RedDotView">
<attr name="dotColor" format="color"/>
<attr name="dotWidth" format="dimension"/>
<attr name="dotHeight" format="dimension"/>
<attr name="dotMiniWidth" format="dimension"/>
<attr name="dotShowRing" format="boolean"/>
<attr name="dotTextSize"/>
<attr name="dotDiameter" format="dimension"/>
<attr name="dotTextColor" format="color"/>
<attr name="dotRingColor" format="color"/>
</declare-styleable>
</resources>
显示效果
- 单一红点的情况,中心距离图片右上角 向左5dp,向下5dp(setOnlyDotMode(true))

- 底部双位数情况,红色中心距离图片右上角自定义,并且红色区域外围有自定义颜色边框

-
显示单位数情况无边框
-
超过100显示...的情况

完!