Administrator
Administrator
Published on 2024-12-22 / 14 Visits
1
0

Modifier绘制角标

代码现实了可拖拽的数字角标,拖动距离大于某个数值时丢弃(清理未读内容)

//将方法放在Modifier类上,就可以在全局任意位置使用
//以下注释假设传入的tag:Int为25

fun Modifier.unread(offset: Offset, tag: Int): Modifier = this.drawBehind {
    if(tag > 0) { //数字小于1时,表示没有未读消息,不显示

        val badgeSize = 16.dp.toPx() // 角标的大小
        val badgeOffset = Offset(x = size.width, y = 0f) // 相对于父元素的位置(右上角)
        val fontSize = 10.sp // 文字大小

        // 绘制红色的圆形角标背景
        drawCircle(
            color = Color.Red,
            radius = badgeSize / 2,
            center = badgeOffset+offset
        )
        // 绘制数字
        val text = tag.toString() //将数字转成String
        val textPaint = android.graphics.Paint().apply {
            textSize = fontSize.toPx()
            color = android.graphics.Color.WHITE
        }

        /*
        * 创建一个float数组,用于接收每一个字符显示时所占宽度
        * 如果都是单字节符号,比如:数字、字母,那么每个索引都应该会是同样的小数
        * 可如果有中文,那么宽度会不一样
        * */
        val widths = FloatArray(text.length)
        textPaint.getTextWidths(text, widths) //执行完后,widths = [20.0, 20.0]
        val textWidth = (text.length * widths[0]) / 2 //因为每个字符都是数字所以宽度一样,所以随便取一个就可以了。得出文字总宽度/2

        val y = (badgeSize - fontSize.toPx())/2
        drawContext.canvas.nativeCanvas.drawText(
            text,
            badgeOffset.x-textWidth+offset.x, //由于角标圆形背景的位置是中心点位置,所以文字的x要减去文字总宽度的一半
            badgeOffset.y+y+offset.y,
            textPaint
        )
    }
}


    var pointerOffset by remember {
        mutableStateOf(Offset(0f, 0f))
    }
//item.tag是一个State,记录角标的数字
        Icon(imageVector = if(selected) item.selectedIcon else item.defaultIcon, contentDescription = item.title, tint = bottomBar.value, modifier = Modifier.pointerInput("draging") {
            detectDragGestures(onDragEnd = {
                if(abs(pointerOffset.x)+abs(pointerOffset.y)>800) {
                    item.tag = 0 //移动距离大于800时清除角标
                }
                pointerOffset = Offset(0f, 0f) //拖动结束,将偏移归0
            })  { _, dragAmount ->
                pointerOffset += dragAmount
            }
        }
        .unread(pointerOffset, item.tag))


Comment