Icon Picker — Jetpack Compose Way
When you’re crafting modern Android apps, user experience is everything. One underrated but highly effective way to enhance UX is to let…
Icon Picker — Jetpack Compose Way
When you’re crafting modern Android apps, user experience is everything. One underrated but highly effective way to enhance UX is to let users customise — and icons play a massive role in that.
But wait, why was I even building an icon picker in the first place? Well, I am currently building an application where the user was required to assign an icon to a type of category. While the first and foremost way to do it is to package all the icons in the app and then use that to show them. But wait, do you know, Jetpack Compose already comes with a lot of icons. So, I got a little curious as to how could I really leverage those and let users set them on their own. How’s this better than all other approaches? Because, I don’t need to package my app with all the icons, also, I don’t need to find all those icons over the internet, download them and manage them.
So, let’s I’ll walk you through building an intuitive Icon Picker using Jetpack Compose. It’s lightweight, clean, and showcases Compose’s reactive flow and state handling.
Preview
Before diving in, let’s look at the preview once, as to what’s the expected output out of this.

Icon Picker
The Core Components
I think, anyone can build the UI if they know the core logic of how to actually retrieve the icons (names, image). So, let’s focus on how to actually achieve that.
Adding Dependencies
First and foremost, let’s not forget to add a dependency to get additional icons.
implementation("androidx.compose.material:material-icons-extended:<LATEST_VERSION>")
If you are using libs.versions.toml , follow the below approach
[versions]
composeBom = "2025.03.01"
[libraries]
androidx-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" }
To check the latest version use the MVN repository — Here
The Icon Util & IconItem Class
The below object has three functions and they have the core logic for these reponsibilities
- Creating Image Vector: This function uses Kotlin reflection to dynamically load an icon from the
Material Iconsset using its string identifier. It attempts to create anImageVectorbased on the icon's ID, which matches the name in thestrings.xmlfile. If it can't find the icon or encounters an error, it gracefully falls back toIcons.Filled.Error - Getting the list of icons: This function in a
List<String>and returns aList<IconItem>. - Sort the list of icons: Once the user starts typing, the
sortIconListfunction ensures that the icons most relevant to the search string appear at the top. The sorting is clever: it looks at the index of the search string inside each icon's ID and orders them based on proximity. The earlier the match, the higher the icon appears in the grid
[embed]
[embed]
Displaying the Icons — UI
For displaying the icons, I am storing the names of the icons in strings.xml as a <string-array> . To show how it looks. Here’s a little peek. The values in the <item> tags, are the icon ids, that could be used to load the icons using reflection.
<string-array tools:ignore="Typos" name="icon_names">
<item>_10k</item>
<item>_10mp</item>
<item>_11mp</item>
<item>_123</item>
<item>_12mp</item>
</string-array>
IconPicker Composable
At the heart of this is the IconPicker Composable. This UI handles everything from displaying the icons in a horizontal grid to allowing real-time search filtering.
We start by retrieving our icon list using a Util.iconUtil.getListOfIcons function that dynamically creates ImageVectors from string resource names.
State management is cleanly handled using remember and LaunchedEffect for filtering the icons list as the user types. Here’s the logic simplified:
- When the search text is empty, show the full list.
- When the user types, filter and then sort the list based on the closest match.
[embed]
Search Bar Composable
The search bas is to simply track what the user is typing. And onTextChange, we update the grid of icons with updated list. The LaunchedEffect ensures that it is triggered on value change of this field and the list is updated
[embed]
IconItem Composable
There’s nothing much to explain about this since, it simply renders the icon in the grid
[embed]
Conclusion
I hope this guide inspires you to embrace Jetpack Compose for its elegant and reactive approach to UI design. Building reusable components like this not only speeds up development but also guarantees a consistent and modern UX for your app users.
If you liked this breakdown, consider clapping or following — happy composing! — Says ChatGPT
Feel free to comment for any questions. Thanks for reading all the way through.
References
I found amazing article that helped me a lot to achieve this. *https://programmingheadache.com/2024/03/15/building-an-icon-picker-for-the-jetpack-compose-material-icons-extended-library/*
Below is the list of icons in strings.xml file. https://gist.github.com/JyotimoyKashyap/939304046a94935cd56e3270c2c164d6.js
메타데이터
- post_id
- b0c81980a596
- slug
- icon-picker-jetpack-compose-way-b0c81980a596
- url
- https://proandroiddev.com/icon-picker-jetpack-compose-way-b0c81980a596
- canonical_url
- https://proandroiddev.com/icon-picker-jetpack-compose-way-b0c81980a596
- author_url
- https://medium.com/@jyotimoykashyap
- status
- ok
- fetched_at
- 2026-06-27 18:20:27