Can you create a Bookmark Button in Jetpack Compose? 💡
🎯 Perfecting Your Jetpack Compose Skills with a Bookmark Button Project 🏆

Let’s say the above piece of UI is today’s task from the planning session, Sounds quite easy, right? Maybe under 10 minutes, we can code a @Composable function?
Here’s a small breakdown of what we’re asked to build:
A bookmark button that has 3 states:
- Bookmarked 📌
- Not bookmarked ❌
- Toggling 🔄
The following requirements could be identified from the gif above:
based on each of these states the UI changes,
state changes should be communicated to the backend
while toggling the button should not be clickable
How would you, as an Android Engineer, implement it?
How about the following?
find the code for this part in this commit:
https://github.com/LloydBlv/BookmarkButton/commit/8310ba9be9da0cd237c4c3cea5ddda2f396ead30
Which results in a simplified version of the design requirement:

Let’s say the design is good enough for the first version of our app and we’ve covered all the requirements and the only thing left is:
while toggling the button should not be clickable
Let’s quickly implement this:
with a one-liner, we could cover that requirement.
So, it seems like there’s not much to do, and we’ve already implemented what we needed! But, let’s see what other things we can explore from here?
What about some performance metrics?
Let’s quickly enable Compose metrics to see how we are doing regarding performance.
https://github.com/LloydBlv/BookmarkButton/commit/3eb6ab89c1050f98044366edde41ec67255ec091
Seems like we’re doing pretty well though, the composable we’ve created is both restartable & skippable and all arguments are marked as stable.
What about some refactorings?
Let’s say we also care about the code readability (we should, right?) and we do a quick refactoring:
We could aggregate two boolean flags and create a state class, we could leverage Kotlin’s sealed interface to achieve better code readability.
Are we done yet? 🤷♂️
It seems like it, but there is much more we could do, and in my opinion, we should do and care about them.
What about configuration changes?
Config changes are usually underrated, and they usually cause weird crashes and unexpected states in the app. Let’s see how our button does after a configuration change.

Here’s what’s happening:
Multiple configuration changes are triggered using the script below:
As we can see, the bookmarked state gets lost after any configuration change. Converting remember
to rememberSaveable
will fix this issue for us, and the last state of the bookmark will be stored/restored after any configuration changes.
Many developers stop here, and this code makes its way to production, but wait, there’s a big missing part in all this!🛑🤯
Guessed it right? Tests!🧪
You’ve probably noticed that we’ve written no tests at all for our feature. This code can make its way to production, and we most probably will be happy with it for a while, but as they say,
“Change is the only constant.”
Sooner or later, some more requirements will come in, and we’d be asked to change something in this code or around it. We can definitely make those changes without having any tests, but how can we make sure we’re not breaking anything while doing those changes?
We can do manual testing, a good amount of manual testing, but again, what’s the guarantee that we have tested every scenario?🤔💔
For more information For more information about testing, check out the Android Developers site.
Now let’s write some tests! 📝✅
Let’s start with some unit tests for these piece of UI,

The above image shows the structure of tests in a newly created (Or a project with no tests 🤦).
Tests setup alongside some tests has been added in the following commit:
https://github.com/LloydBlv/BookmarkButton/commit/616ecb9890be11735e18c5ba6fc4464fe735b823
Tests above ensure that each state of our bookmark button is set correctly as we expected, given the product requirements. 🎯📊
But we’re NOT done yet; we have not tested the transition between these states. We should make sure when the state is toggling, the progress bar is shown and disappears correctly. 🔄🛠️
So far we’ve come up with following tests:

These tests ensure a more robust product, especially behavior-wise. But how can we make sure our UI remains robust throughout different feature implementations in a team or organization? 🤝🔍
Screenshot testing to the rescue!📸🛡️
Screenshot testing simply means taking screenshots/snapshots of different pieces of UI in an Android application and later verifying that piece of UI results in the same screenshots. If not, git hooks/CI pipelines could fail to notify about some unexpected changes in the current PR. 🚨🔧
for more information about screenshot testing:
As the above link, there are many screenshot testing libraries, We will be using Roborazzi for this article:
By having the above implementation, we can generate base/gold screenshots for our bookmark button in different states. These screenshots will be verified in our CI pipeline every time a PR/MR is raised, ensuring our UI’s integrity. 🖼️👍

The following images are generated and committed to our codebase:


Are we done yet?
There are still several aspects we can address:
- 🎨 Composing Previews
- 👀 Checking how the UI looks on different screen sizes, small phones, tablets, etc
- ♿ Enhancing Accessibility
- 🔧 Configuring Unit Tests
- 📱 Testing our feature on lower Android APIs
- 😟 Handling scenarios where toggling fails (unhappy paths)
We’ve realized that developing a feature involves more than just completing the feature’s code and integrating it into the codebase. Often, these additional considerations are overlooked.
What else can you think about what’s important when doing a feature in the world of Android? What’s the definition of done (DoD) in your team or organization? Let me know in the comments!
The full project code can be found here:
Great job on making it to the end of this article! 💪
- Follow my YouTube channel for video tutorials and tips on Android development 📺📺
- If you need help with your Android project, Book a 1:1 or a Pair-Programming meeting with me, Book a time now 🧑💻🧑💻🧑💻
If you like this article please can you do me a little favour and hit the 👏clap button as many times! I really appreciate your kindness x❤️👊