Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
@Composable
fun RepeatingButton(
modifier: Modifier = Modifier,
onClick: () -> Unit,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
elevation: ButtonElevation? = ButtonDefaults.elevation(),
shape: Shape = MaterialTheme.shapes.small,
border: BorderStroke? = null,
colors: ButtonColors = ButtonDefaults.buttonColors(),
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
maxDelayMillis: Long = 1000,
minDelayMillis: Long = 5,
delayDecayFactor: Float = .15f,
content: @Composable RowScope.() -> Unit
) {
val currentClickListener by rememberUpdatedState(onClick)
var pressed by remember { mutableStateOf(false) }
Button(
modifier = modifier.pointerInteropFilter {
pressed = when (it.action) {
MotionEvent.ACTION_DOWN -> true
else -> false
}
true
},
onClick = {},
enabled = enabled,
interactionSource = interactionSource,
elevation = elevation,
shape = shape,
border = border,
colors = colors,
contentPadding = contentPadding,
content = content
)
LaunchedEffect(pressed, enabled) {
var currentDelayMillis = maxDelayMillis
while (enabled && pressed) {
currentClickListener()
delay(currentDelayMillis)
currentDelayMillis =
(currentDelayMillis - (currentDelayMillis * delayDecayFactor))
.toLong().coerceAtLeast(minDelayMillis)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment