Thanks to Jetpack Compose, implementing gestures is easier than ever. The only thing we need to assign an action to a gesture, is a Composable
and a lambda.
We are going to see how to add this functionality with code samples for a Composable
that is representing a vertical clock.
How to add vertical gestures
To add gestures, we are going to need modifiers. In this case, to recognize a vertical swipe, up or down, the scrollable
modifier is needed, which takes the orientation of the gesture and a state.
This state is provided by rememberScrollableState
, and its delta
argument is what is going to tell us if the gesture is representing a scroll down or a scroll up. If the delta
argument is negative, then the user is scrolling up, and you can imagine what happens if the delta
is positive.
This makes sense as the UI is defined by two coordinates axis that have the (0,0) point in the upper left corner.
Here you have a sample code with the scrollable
modifier implemented.
.scrollable(
orientation = Orientation.Vertical,
state = rememberScrollableState { delta ->
when {
delta < 0 -> onScrollUp(delta)
delta > 0 -> onScrollDown(delta)
else -> {}
}
delta
}
)
KotlinHow to add horizontal gestures
The same principle is applied here. We use the scrollable
modifier, but with the orientation specified as horizontal.
Following what we said before about where the (0,0) point is in the coordinates, if the delta
is positive, a swipe right is being done, and if it is negative, we are going to register a swipe left.
If we want to apply a horizontal and a vertical gesture to the same Composable
, then we would need to add to scrollable
modifiers to it.
Here there is an example of the horizontal gesture.
.scrollable(
orientation = Orientation.Horizontal,
state = rememberScrollableState { delta ->
when {
delta < 0 -> onSwipeLeft(delta)
delta > 0 -> onSwipeRight(delta)
else -> {}
}
delta
}
)
KotlinHow to add tap gestures
If we want to manage double taps or a long press, we have to use another modifier, in this case, the one called pointerInput
.
Here with the detectTapGestures
function we can specify an action for each of the different kinds of taps, with a lambda, as you can see in the following example.
.pointerInput(Unit) {
detectTapGestures(
onPress = {},
onDoubleTap = {},
onLongPress = { onLongPress() },
onTap = { onClick() }
)
}
KotlinWith all that, we could have the following Composable
, which represents a timer that can be controlled with that all those taps and gestures.
fun VerticalClock(
modifier: Modifier = Modifier,
clock: Clock,
onClick: () -> Unit,
onLongPress: () -> Unit,
onScrollDown: (Float) -> Unit,
onScrollUp: (Float) -> Unit,
onHorizontalScroll: (Float) -> Unit
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
.fillMaxWidth()
.pointerInput(Unit) {
detectTapGestures(
onPress = {},
onDoubleTap = {},
onLongPress = { onLongPress() },
onTap = { onClick() }
)
}
.background(MaterialTheme.colorScheme.background)
.scrollable(
orientation = Orientation.Vertical,
state = rememberScrollableState { delta ->
when {
delta < 0 -> onScrollUp(delta)
delta > 0 -> onScrollDown(delta)
else -> {}
}
delta
}
)
.scrollable(
orientation = Orientation.Horizontal,
state = rememberScrollableState { delta ->
when {
delta < 0 -> onSwipeLeft(delta)
delta > 0 -> onSwipeRight(delta)
else -> {}
}
delta
}
)
) {
with(clock) {
ClockPair(
verticalAlignment = Alignment.Bottom,
firstDigit = firstDigit,
secondDigit = secondDigit
)
ClockPair(
verticalAlignment = Alignment.Top,
firstDigit = thirdDigit,
secondDigit = fourthDigit
)
}
}
}
KotlinFeatured image by Liana Mikah on Unsplash
If you want to read more content like this and support me, don’t forget to check the rest of the bolg or subscribe here to get an email every time I publish new content.