“Composing” the Flutter counter app with Jetpack Compose: Part 1

I experienced the comfort of getting away from designing my layouts using XML when I shifted towards Flutter. Having spent almost 3 years working with the Declarative UI, I feel that it is the future. The introduction of Jetpack Compose in the case of Android and SwiftUI in the case of iOS says a lot about that feeling. Recently I got my hands dirty with Jetpack Compose and I must say, it felt amazing. Native development won’t be the same after this.
Note: As of writing this article, the compose is at 1.0.0-beta05. Things might change with further updates. Please check the latest updates here.
After going through the documentation, I found a lot of similarities in the way things are working in compose and Flutter.
To start, simply go to this link and start following the steps. Here, the foundation section is the most important one. It’ll help you start thinking in compose, what to do and not do while working with compose, managing state, and the Lifecycle of a composable.
It seems like a lot, but it is very important to understand the basics before working on a project.
💻 As a Flutter developer, after going through the basics, my first instinct was to work on the Counter app that is built by default when you create a new Flutter project.
Let me walk you through all you need to do to create one.
Note: I would be pacing through the basic introduction of Jetpack Compose during the initial steps here. I would be giving you a path to walk on to understand the basics and jump on to creating your first app in Compose.
Step 1:
Create a new project that includes support for Jetpack Compose by default. To do this, go to this link and follow the steps. After you are done with the setup, feel free to go to this link to get a taste of what you are getting into.
Step 2:
Here, I am assuming that you are now familiar with what @Composable and @Preview annotations are and how you can put some basic set of Widgets on a screen and modify their properties.
Next, you would want to wrap your head around the idea of a declarative UI pattern. For that, go to this link.
Few key parts that I would want you to focus on in this document would be:
- Understand how compose handles rebuilding the whole UI tree and how to manage it well when you would want to update a certain UI element on the screen (Recomposition)
- You would also want to focus on the things that one should NOT do while working with Compose. Referred to as “side-effects” in the doc.
- Next, focus on the part where you get to know how:
3.1 Composable functions can execute in any order - Don't let one of your composable depend on another.
3.2 Composable functions can run in parallel - Optimization and one side-effect you should keep in mind. 3.3 Recomposition skips as much as possible - Optimization and oh yeah, they mention the side-effect again. Must be really important to remember that. 3.4 Recomposition is optimistic - Compose expects to finish recomposition before the parameters change again.3.5 Composable functions might run quite frequently - Pass the data to Compose using mutableStateOf or LiveData. What's that? We'll get to it.
Now that you have read the whole document, you are ready to move ahead with a better understanding of Compose.
Before we move ahead, do you know what the word idempotent stands for? No? Please read the whole document again 🙂
Step 3:
You are nearly there.
We are done with the very basics of Jetpack Compose, and now comes one of the most important parts: State.
MutableStateOf:
Remember we read about mutableStateOf
and LiveData
in 3.5 above? We would get to LiveData and more in Part 2 but for now, let’s stick to mutableStateOf
and see what all it can do to help us maintain state in our app.
Now we already know that a composition can only be produced by an initial composition and updated by recomposition. The only way to modify a composition is through recomposition. So what mutableStateOf
does is it creates a MutableState
, which is an observable type in Compose. Any changes to its value will schedule recomposition of any composable functions that read that value.
Pretty neat right? But while making changes to a variable, you would want the state to be preserved across recompositions i.e. you would want your state to be remembered right?
We have just the composable for that called, you guessed it, remember.
Remember composable:
var name by remember { mutableStateOf("") }
Here, you can use this name variable to update your UI by passing it on to a Composable as a parameter. Although remember helps you retain state across recompositions, the state is not retained across configuration changes. For this, you must use rememberSavable.
Example:
var name by rememberSaveable { mutableStateOf("") }
Stateless composable:
One more thing to note in the case of State in composable is that one should be working with Stateless composable i.e.
composable does not hold its own state and thus it is not tightly coupled to how its state is stored. This way, composable is easy to reuse and test.
To do this, you can use state hoisting. I feel the example here is more than enough for you to understand the concept.
Alright, looks like we are all set to work on our beloved Counter app.
Let’s begin
First, let’s revisit the app we created in Step 1. In that update the MainActivity.kt file with the following gist.
Run the app on your emulator/device and click on the FAB to see the count increasing on the UI.
Wish to change the theme and match it to the one used in the Flutter counter app? Simple, inside ui.theme folder open Color.kt file and replace the values as :
val Blue200 = Color(0xFF90CAF9)
val Blue500 = Color(0xFF2196F3)
val Blue700 = Color(0xFF1976D2)
and then, open the Theme.kt file and update it as:
primary = Blue200,
primaryVariant = Blue700,
Rebuild the app and Voila!, the theme is the same as that of the default Flutter counter app.
In Part 2, we would modify this app to work with ViewModel for State management.
How many claps does this article deserve?
If you find this article useful, please click the 👏 button and share to help others find it! Feel free to clap many times (10💥, 20💥 , or maybe 50💥 ?) It fuels my focus to write more of it.
Connect with me on LinkedIn or say hi on Twitter, mentioning this article. You can drop an e-mail at annsh29@gmail.com as well.
Check out my series on various Flutter widgets here -