Hi all! This is the 2nd article of this series where we’re going to learn how to use gestures in Jetpack Compose. Let’s start, as we used to, with a preview:

If you want to follow along or want the code of the UI, check out this repository:

Note that compose version is 1.0.0

That’s a digest of what we are going to build:
The item, the funnel-shaped view, and the explosion will be updated based on the horizontal offset of the item.

1. UI

1.1. Side shape

We want to draw a funnel shape and a particle. The bottom radius of the funnel would be calculated using the particle radius.

  1. Long radius.
  2. Short radius.

As shown above, an arc is a segment of the ellipse bounded by a given rectangle. The two red rectangles are horizontally translated by the minus value of the short radius to avoid cutting vertically the funnel.
To draw this shape, we need to add two line segments, which are AD and BC. forceMoveTo parameter in Path.arcTo() performs this while creating these arcs. However, we need to follow a pattern while producing this shape. BADC, CDAB, DCBA, or ABCD. We will go with the last one.
Now we need two other values to create an arc. These are startAngleDegrees and sweepAngleDegrees. The zero degrees is the point on the right-hand side of the oval that crosses the horizontal line that intersects the center of the rectangle and with positive angles going clockwise around the oval.
So, for AB, we will go from 180° to 90°. So, the sweep angle would be -90°. And for CD, we will go from 270° to 180°. Therefore, we will use the same sweep angle, which is -90°. That’s it.

Since we want to draw something besides the swiped item, we will wrap the item in a Box. We will draw the funnel using DrawScope.drawPath(), and we will add the particle by drawing a circle.

1.2. Explosion

We can create a simple explosion by translating some points from the center of a circle to its edges.

As depicted above, the horizontal and vertical translations are calculated with the sin or cos of the particle angle multiplied by the explosion radius.
Following the red arrows, we will determine the particle translations. So, we will make it twice as faster. However, technically, the algorithm stays at the same complexity, which is O(n).
Finally, we check if the current angle is not equal to 0 or PI to avoid drawing the circle twice on the x-axis.

2. Gesture animation

To build a swipe animation, we need to create a modifier that is capable of receiving drag events. This is where Modifier.pointerInput() is beneficial.

Modifier.pointerInput() creates a modifier for processing pointer input within the region of the modified element.

Inside its block, in a nutshell, we await for a touch event, then for a positive horizontal drag because we are implementing this on one side. When we get those, based on the velocity and the target offset, we choose between sliding back or sliding away the element. The offset value will be a parameter since we want to share it with other Composables and will be used as an offset of the current element.

That’s an altered version of what the google team provided here.

Afterward, we add the swipeToDelete modifier along with its parameters to the item layout.

2.1. Side shape

At first state, we want that the funnel and the particle placed together just outside the screen. Since we didn’t specify a width to our canvas, the circle, the particle that is, will be drawn around a center placed where its parent starts. Hence, half of it will be visible to the user. So, minus its radius is the initial translation. And it will be added to the offset of the item to allow it to follow the item along the swiping process.
For the funnel shape, the initial translation should be minus its width and minus the particle radius so that the circle takes the lead. Now, we want to move it toward the opposite direction when it totally comes out. That is when its translation is positive. To solve this, we create an extension function that negates the translation whenever being positive.

2.2. Explosion

Considering that we are going to translate the explosion particles, we need to translate their parent, which is the Canvas. So, we will use Modifier.offset() as we did when we implemented the swipe feature. We want to make the explosion blow up from the beginning of the particle of the side shape. Therefore, its initial translation will be minus the diameter of the circle. And to obstruct the explosion from trailing the item, we will use coerseAtMost() with the funnel width.

Now, we want to glide the explosion particles to create a wave motion. For that, we will create a state that holds a percentage of this procedure. It will be updated whenever funnelTranslation is positive(before being negated by the function we created). Afterward, we multiply the translations values with this percentage. And finally, we want to update the alpha of these particles too.

3. External links and source code

Animation | Jetpack Compose | Android Developers

Here is the full Github repository for this article:

That’s a wrap. Here, we reach the end of this article. See you in the next final one.

Become Author

We are making content on new declarative UI kit Jetpack Compose, if you are willing to build content join us and we will help you get started.

Here We Go Again : (

if (article == helpful) {
    println("Like and subscribe to blog newsletter.")
} else {
    println("Let me know what i should blog on.")

This site uses Akismet to reduce spam. Learn how your comment data is processed.