Member-only story
Finite State Machine as a ViewModel for Jetpack Compose Screens
In this article, I will explicitly define a practical, step-by-step guide to model complex UI Screens using the Finite State Machine. I will also demonstrate how to implement FSM in Kotlin and Jetpack Compose, although the techniques described in this article are easily transferable to any other language or framework.
Understanding the Problem
As we already know, the Jetpack Compose framework works in three phases: composition, measurement, and rendering. To build an interactive UI that reacts to the users actions or any other events, all you need to do is declare a different appearance for a particular state. Then Compose framework will handle all changes for you whenever these states changes are occurring. Sounds good, however for real-world applications with complex screens and user flows, we might need to have too many states variables that may conflict in the race of hardcoded conditions. Also, most apps usually contain side effects, e.g., changing a state from the network response, and so on. Moreover, as we all remember, the increase in the number of condition variables increases the complexity of the code and computation exponentially.
One of the ways to solve all those problems is a Finite State Machine.
Let’s use one of the screens from my StudyCards app as an example to detect the problem and test the solution. This screen is not too complex, so the implementation will not be too long. However, it is complicated enough to see the benefits from the solution.
An Example Screen
I wanted to build a screen representing the deck of cards as a table of two columns, one column for the front side value and the second for the value of the backside. In this screen, a user can modify existed deck or create a new deck of cards. Here is the list of screen features:
- Add a new flash card;
- Edit card;
- Delete cards from the deck;
- Edit the name of the deck itself;
Also, I wanted to allow all of these user interactions on one screen!! Look at Figure 1.


