PicoLauncher: Building a Minimal Android Launcher

I got tired of bloated home screen launchers, so I built my own. Here's what I learned about the Android launcher APIs, building for one-handed use, and the value of deliberate minimalism.

My phone’s home screen has always bothered me. Launchers pile on widgets, icon packs, animations, and customization menus that I’ll open once and never touch again. The default AOSP launcher is cleaner, but it still defaults to an icon grid I find visually noisy.

What I actually want is a list of the apps I use most, a search bar that finds anything else, and my wallpaper. That’s it.

PicoLauncher is what I built.

What it is

PicoLauncher is a minimal Android home screen launcher written entirely in Kotlin. By default the home screen shows a short list of pinned or recent apps as text, with no icons. Swipe up for the full app drawer with live search, and swipe left or right to open apps you’ve assigned to those gestures.

There’s also a hold-to-reveal mode, where long-pressing the home screen opens a radial icon menu. It’s handy for quick access to a few apps without cluttering the screen.

Why I built it

The honest answer is that I built it as a learning project. I’d been doing web and backend work for a while and wanted to go deeper on Android. Writing a launcher turned out to be a great way to learn: you touch deep Android APIs (intent filters, package manager, home screen contracts), you have to handle the lifecycle carefully because your app is always running, and the UX constraints are tight enough that every design decision is interesting.

The interesting parts

The Android launcher contract

To be recognized by Android as a launcher, your app needs the right intent filter in its manifest:

<intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.HOME" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Simple enough, but there’s a lot more to handle: back button behaviour, the recents API, the case where the user installs or uninstalls an app while the launcher is visible, and making sure the launcher survives configuration changes (rotation, dark and light mode) without flickering.

Android’s PackageManager gives you all installed apps via queryIntentActivities. I cache this and update it reactively using a BroadcastReceiver that listens for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED, and ACTION_PACKAGE_REPLACED.

The live search filters by both app label and package name, which helps with apps that have opaque names, and uses fuzzy matching so a partial word still finds what you want.

Hold-to-reveal radial menu

This was the most visually interesting feature to build. The radial menu opens as a circle of icons around the press point. Getting the animation right (spring-based expansion from the hold point, icons arranged in a calculated arc) took more custom drawing than I expected.

I used Canvas drawing on a transparent overlay View rather than trying to position individual ImageViews, which would have required calculating absolute screen coordinates. The draw-everything-yourself approach gave me much more control over the animation curves.

Widgets

Adding widget support late in the project was the most painful feature. Android’s widget embedding API is old and involves AppWidgetManager, AppWidgetHost, and a manual view inflation flow very different from modern Compose or View-based layouts. The widget configuration intents, the resize handles, and keeping widgets alive through launcher recreation all have subtle edge cases.

If I were starting over I’d design the widget slot system earlier, because retrofitting it into an existing layout was awkward.

Theming

One feature I’m happy with is the independent theming for the home app list and the full app drawer. You can set different font sizes, typefaces (default, monospace, serif), and text colours for each, so your home screen can be minimal white monospace while your app drawer is larger coloured text. It’s a small thing, but it makes the launcher feel like it was designed for you.

Try it

The project is on GitHub. Clone it, open it in Android Studio, and run it on any Android 15+ device or emulator. I use it as my daily launcher. The home screen is genuinely just my five most-used apps and a search bar, and I haven’t missed the icon grid at all.