Adaptive Icons: Winter is Coming ❄️

Moyinoluwa Adeyemi
Power the People
Published in
4 min readJan 31, 2018

--

We might all have heard about the impending day of judgement, when new and existing Android apps will be required to target API level 26 or higher. While there are some shiny new developer things in Android O — downloadable fonts, adaptive icons etc., there are also some not so shiny things. Background execution limitations have become stricter and all notifications are going to need to have a channel. Admittedly, migrating an existing project might be easier and more flexible with a side project, but what is this going to mean for a developer working in a team on a large codebase?

The best time to start is now if you haven’t already. We are also on that mission, and I plan to share our steps in our process to take advantage of all Android O has to offer.

Adaptive icons

A lot has been written about this topic already. Ian Lake and Nick Butcher have some of the most comprehensive posts about it. I’ll dive into the basics first and then highlight the interesting part of converting our icon.

Adaptive icons were introduced to resolve the problem created from the visual imbalance among icons on an Android device, based on the creative freedom initially given to Android developers. With adaptive icons, all icons are required to adapt to some general shapes — the circle, tear drop and square, and are expected to look great across these shapes.

The best way to achieve this is with VectorDrawables. The icons typically have a 108 by 108 sized foreground and background layer which can either be a color, drawable or mipmap resource. The background layer has to be completely opaque while the foreground layer can be transparent. There’s a little caveat though. To ensure that the image on the foreground layer doesn’t get cropped off when the background shape changes, it is recommended that it doesn’t exceed a radius of 33 from the center (the safe zone).

Our current icon. A PNG file

The first step I took was to add a mipmap/ic_launcher folder to our res folder since it did not exist before. Next, I created an xml file named ic_launcher with a resolution of anydpi-v26. The ic_launcher file consisted of a root tag named <adaptive-icon> which enclosed two other tags; the <foreground /> and the <background />. android:drawable which was called in these inner tags accepts a color, drawable or mipmap resource. All adaptive icons must include these two tags.

<adaptive-icon 
xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/blue" />
<foreground android:drawable="@drawable/ic_logo_foreground" />
</adaptive-icon>

Since the background of our icon is plain, I used a blue color resource as the background. For the foreground, I got a white 108 by 108 SVG icon without the shadows and blue background from Nick Stevens, our designer. I adjusted it a bit in Sketch to ensure that no part of the white icon extended past the safe zone and converted it into a VectorDrawable with this tool.

If you look closely at the image above, you’ll find that it has shadows with varying degrees of intensity. The left side of the icon has a dark inner shadow, the middle is darker while the right side is light and gradually fades off. For the inner shadow on the left side, I drew a shape with a single transparent color. For the right side, I drew another shape, this time with multiple stops which transitioned from very transparent to completely transparent. This shape was then overlapped with the shadow on the left to create the darker effect in the middle.

quick maths.

The foreground.xml file was optimized with avocado and the manifest file was updated with the new icon.

<application
android:icon="@mipmap/ic_launcher"

Finally, I used Nick Butcher’s AdaptiveIconPlayground app to confirm that the icon and shadows looked good on all the different shapes.

That’s all folks! You can find the code for this article on GitHub. Please leave a comment below if you have any suggestions or feedback.

--

--