Modelling dating cards navigation with Appyx

Articles in the series so far:

Zsolt Kocsi
Bumble Tech
Published in
6 min readOct 17, 2022

--

  1. Appyx is released! (1.0-alpha02)
  2. Appyx vs Jetpack Compose Navigation

Modelling dating cards

In the previous articles, we’ve shown Appyx to be a powerful navigation library for Android apps using Jetpack Compose. It comes packed with many exciting features (for a comprehensive list, see the bottom of the previous articles).

But Appyx is more than just a navigation solution for switching screens — it’s model-driven navigation:

You can use it to implement any kind of navigable component you can think of, by describing its possible states.

Today we’ll be seeing how this approach can be used to create complex in-screen navigation behaviours and we’ll be implementing this dating card mechanism:

The process is simple: first, we’ll model these cards with states and state transitions, and then we’ll associate these states with UI properties.

Using this model and the provided UI properties, Appyx does all the rest for us, from handling lifecycles to running transitions.

Let’s get started!

Step 1 — Define possible states

With a dating card mechanism, we’ll have card-like navigation targets that can be in these distinct states:

Step 2— What’s on screen? What’s removed?

With Appyx, we can define which states are considered on or off the screen. This is a simple mapping to Boolean values:

Once any navigation target (in our case: a profile card) reaches a state where this value is false, Appyx will remove them from the UI composition. Here we can see that Queued, VoteLike, VotePass are considered off the screen.

However, this is only about UI rendering efficiency — the related Nodes will remain alive without their view, unless the state in question is also defined as a “final state”. Reaching those states will result in fully destroying them.

This information can be passed on to any NavModel defined in Appyx:

Step 3 — Describe state transitions

It’s time to describe the rules for how a card can move from one state to another:

The user’s main point of interaction is always with the top card. Whenever a card is voted on, it will be a trigger for additional state changes — the bottom card now becomes the new top card, and all remaining cards are promoted in the queue until they eventually, in turn, become a bottom card. We can capture this progression with this mapping:

Step 4 — Add operations

Let’s take a look at one operation as the rest will look very similar. This is how a state change of TopVoteLikewould be applied to the list of elements:

The voteLike() method passes the operation to the Cards navigation model. In addition, it also calls promoteAll(). As we described in Step 3, as soon as a Top card is voted on, all other cards should be promoted to their next states — this operation does exactly that:

Step 5— Associate states with UI properties

Now that we’re done modelling our dating cards on an abstract level, it’s time to visualise them and make them look fancy!

Here Appyx gives us a complete freedom of choice.

With Appyx, we can use any UI property for transition animations that we can represent with a Compose Modifier.

That’s a lot of power! And the best part is that it’s very easy to do so. Let’s begin by defining the properties we’ll want to animate. This is purely our choice:

Next, let’s define some actual values representing our key states:

Finally, we use them in our TransitionHandler to create a Modifier:

Finally — the results!

Now we’re ready to tie all of this together. In real life, we’d trigger NavModel operations based on UI interactions and business logic. However, in the interest of a simple demo, we’ll do it with a script.

Let’s create an instance of our custom Cards navigation model and run this:

Which gives us this:

But wait! We only defined a few states and UI properties. How does that result in this awesome animation?

Let’s deconstruct what’s happening.

The pipeline of events

  1. We trigger a NavModel operation (e.g. cards.voteLike())
  2. The operation causes a state change in the model, like setting a newtargetState on any element.
    In the case of a VoteLike operation, we’ve seen in Step 4 that the element with a current state of Top gained a new targetState of VoteLike.
  3. Appyx runs a Compose transition between these states. It asks our TransitionHandler implementation to map the transition to Modifiers we defined. The values in the Modifiers are animated between the UI property endpoints that we defined in our Props class instances.

Some visual “aha!” moments

Based solely on our implementation, voteLike() resulted in all other cards being promoted — so we not only see the top card moving but also the bottom card automatically becoming the new top card.

And because the related Props we defined in Step 5 are such that a bottom card has 85% scale and the top card has 100%, we see it coming towards us as it scales up to match the new value.

We assigned large values for positive/negative offset and rotation to VoteLike and VotePass states. When a top card is voted on, it initially has no offset and no rotation — as these properties are animated towards new target values, we see the card automatically flying off the screen in a rotational manner.

Extending the navigation model

Adding new states and behaviour to a NavModel is very easy.

Noticed something interesting? In the video capture, the swiping lingers on before making an actual vote and it sometimes swings in the opposite direction:

This behaviour is usually used for in-app tutorials. Here it’s happening as a result of the additional operations indicateLike() and indicatePass() in the demo script that were not in our original plans.

Implementing this extra behaviour can be achieved quite simply:

  1. Add two more possible states: IndicateLike, IndicatePass
  2. Add the related operations that move a Top card to said states
  3. Represent these states with some amount of rotation and angular offset in the TransitionHandler

And done!

What next?

I hope you found this demo interesting! You might have a ton of questions (e.g. “Ok, but how do I swipe the cards with gestures?”) — keep them coming so we’ll know what topics to focus on next. There’s a lot more to discover about Appyx, and we’ll keep posting more articles — stay tuned.

In the meantime, you can:

If you play around with it and implement a cool new NavModel — reach out, we’d love to know about it!

--

--