Compose中常用的一些Modifier的扩展ui方法记录
- 关于
- 防快速点击
- 虚实分割线
- 虚线边框
- 阴影
关于
本篇主要记录一些开发中可能用到的常用方法的扩展记录,包括防快速带点击,画虚实线divider,画虚线边框,绘制阴影等。
防快速点击
inline fun Modifier.singleClickable(
debounceDuration: Long = 400L,
enabled: Boolean = true,//中间这三个是clickable自带的参数
rippleEnabled: Boolean = true, //是否开启水波纹
onClickLabel: String? = null,
role: Role? = null,
crossinline onClick: () -> Unit
): Modifier = composed {
var lastClickTime by remember { mutableStateOf(value = 0L) }
val eventAction: () -> Unit = {
val currentTimeMillis = System.currentTimeMillis()
if (currentTimeMillis - debounceDuration >= lastClickTime) {
onClick()
lastClickTime = currentTimeMillis
}
}
if (rippleEnabled) {
clickable(enabled, onClickLabel, role, eventAction)
} else {
clickable(
interactionSource = NoRippleInteractionSource(),
indication = null,
enabled = enabled,
onClickLabel = onClickLabel,
role = role,
onClick = eventAction
)
}
}
class NoRippleInteractionSource : MutableInteractionSource {
override val interactions: Flow<Interaction> = emptyFlow()
override suspend fun emit(interaction: Interaction) {}
override fun tryEmit(interaction: Interaction) = true
}
虚实分割线
/**
* 虚实分割线
* 实线虚线长度都为10f 根据实际需求更改下方PathEffect里面的float参数数据
**/
internal fun Modifier.dashedDivider(strokeWidth: Dp, color: Color) = drawBehind {
drawIntoCanvas {
val paint = Paint()
.apply {
this.strokeWidth = strokeWidth.toPx()
this.color = color
style = PaintingStyle.Stroke
pathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f)
}
it.drawLine(
Offset(0f, size.height / 2),
Offset(size.width, size.height / 2),
paint
)
}
}
使用如下:
Divider(
color = Color.Transparent,
modifier = Modifier
.fillMaxWidth()
.dashedDivider(1.dp, Color(222, 46, 66, 255),
)
)
效果如下:
虚线边框
/**
* 虚线边框
* @param width 虚线宽度
* @param radius 边框角度
* @param color 边框颜色
* 虚实间隔也是写死的10f
**/
internal fun Modifier.dashedBorder(width: Dp, radius: Dp, color: Color) =
drawBehind {
drawIntoCanvas {
val paint = Paint()
.apply {
strokeWidth = width.toPx()
this.color = color
style = PaintingStyle.Stroke
pathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f)
}
it.drawRoundRect(
width.toPx(),
width.toPx(),
size.width - width.toPx(),
size.height - width.toPx(),
radius.toPx(),
radius.toPx(),
paint
)
}
}
使用如下:
Spacer(modifier = Modifier.height(24.dp))
// 正方形
Box(
modifier = Modifier
.padding(top = 16.dp)
.width(120.dp)
.height(120.dp)
.align(Alignment.Start)
.dashedBorder(
width = 2.dp,
color = Color(222, 46, 66, 255),
radius = 0.dp
),
contentAlignment = Alignment.Center,
){}
Spacer(modifier = Modifier.height(24.dp))
//圆形
Box(
modifier = Modifier
.padding(top = 16.dp)
.width(120.dp)
.height(120.dp)
.align(Alignment.Start)
.dashedBorder(
width = 2.dp,
color = Color(222, 46, 66, 255),
radius = 90.dp
),
contentAlignment = Alignment.Center,
){}
效果如下:
阴影
fun Modifier.drawShadow(
color: Color = Color.Black.copy(alpha = 0.1f),
borderRadius: Dp = 0.dp,
blurRadius: Dp = 8.dp,//模糊半径
offsetY: Dp = 0.dp,
offsetX: Dp = 0.dp, //便宜
spread: Dp = 0f.dp, //扩散
) = drawBehind {
this.drawIntoCanvas {
val paint = Paint()
val frameworkPaint = paint.asFrameworkPaint()
val spreadPixel = spread.toPx()
val leftPixel = (0f - spreadPixel) + offsetX.toPx()
val topPixel = (0f - spreadPixel) + offsetY.toPx()
val rightPixel = (this.size.width + spreadPixel)
val bottomPixel = (this.size.height + spreadPixel)
if (blurRadius != 0.dp) {
frameworkPaint.maskFilter =
(BlurMaskFilter(blurRadius.toPx(), BlurMaskFilter.Blur.NORMAL))
}
frameworkPaint.color = color.toArgb()
it.drawRoundRect(
left = leftPixel,
top = topPixel,
right = rightPixel,
bottom = bottomPixel,
radiusX = borderRadius.toPx(),
radiusY = borderRadius.toPx(),
paint
)
}
}
使用:
Spacer(modifier = Modifier.height(24.dp))
Box(
modifier = Modifier
.size(120.dp,120.dp)
.drawShadow(color = Color.Black.copy(alpha = 0.4f),
offsetY = 8.dp, offsetX = 8.dp,
spread = 4.dp,
)
.background(
color = Color(51, 204, 255, 255),
shape = RoundedCornerShape(8.dp),
),
) {
}
效果如下: