Skip to main content

Command Palette

Search for a command to run...

Debouncing Clicks in Compose

Updated
2 min read
Debouncing Clicks in Compose
J

Hey! I’m Joe! I’m an Android developer who is passionate about the human side of software development.

I recently needed to add a debouncing operator on my button clicks in a Compose multiplatform project. I thought I'd share my solution in case it was useful to someone else.

First, we define an EventProcessor interface. The concrete implementation will be responsible for debouncing our clicks.

internal interface EventProcessor {
    fun processEvent(event: () -> Unit)

    companion object {
        val buttonClickMap = mutableMapOf<String, EventProcessor>()
    }
}

The implementation:

private const val DEBOUNCE_TIME_MILLIS = 1000L

private class EventProcessorImpl : EventProcessor {
    private val now: Long
        // this is being used in Compose multiplatform 
        // switch out with whatever millisecond provider you want
        get() = Clock.System.now().toEpochMilliseconds()

    private var lastEventTimeMs: Long = 0

    override fun processEvent(event: () -> Unit) {
        if (now - lastEventTimeMs >= DEBOUNCE_TIME_MILLIS) {
            event.invoke()
        }
        lastEventTimeMs = now
    }
}

The Composable function where our EventProcessor will be used and a helper function for getting this button's EventProcessor

internal fun EventProcessor.Companion.get(id: String): EventProcessor {
    return buttonClickMap.getOrPut(
        id
    ) {
        EventProcessorImpl()
    }
}

@Composable
fun debouncedClick(
    id: String = randomUUID(),
    onClick: () -> Unit,
): () -> Unit {
    val multipleEventsCutter = remember { EventProcessor.get(id) }
    val newOnClick: () -> Unit = {
        multipleEventsCutter.processEvent { onClick() }
    }
    return newOnClick
}

Here is an example of it being used:

PrimaryButton(
    onClick = debouncedClick {
        // handle click
    },
) {
    Text("Button")
}

Full code:

https://gist.github.com/j-roskopf/990baa5beef767fbb2fae8cce33e2529

More from this blog

Joe's Android Blog

25 posts