I’m trying to create drop shadows for my Android app icons that match the design from Figma. These icons need to work in navigation bars, custom views, and buttons. I’ve tested different approaches like nine-patch images and layer-list drawables, and I can get the shadow effect working. But here’s my issue - when I add the shadow, it creates extra padding around the drawable which makes the main icon appear smaller than it should be. This becomes a real problem when I try to use these shadow drawables inside selectors along with other images because the sizing gets inconsistent. Has anyone found a good solution for this? I want to keep the shadow effect but maintain the original icon dimensions.
try clipToPadding=“false” on your parent container. had the same issue with icon shadows bleeding into margins. this lets the shadow render outside the padding area without messing with your icon size. works great with layer-lists too.
Shadow padding kills productivity when you’re juggling dozens of icons across different app states.
I hit this on a recent project - designers kept changing shadow specs and I was manually redoing drawables every single time. The real problem isn’t just padding, it’s keeping everything consistent when shadow properties change.
I ended up automating the whole pipeline from Figma to Android drawables. Built a system that pulls shadow data straight from Figma files and spits out proper layer-lists with calculated bounds that keep your original icon dimensions.
It handles all the math - insets, shadow offsets, blur radii - so drawables come out pixel perfect. When designers update shadows in Figma, new drawables generate automatically with padding compensation baked in.
This killed all the manual tweaking and guesswork. No more broken selectors or wonky sizing across icon states. Just perfect drawables every time.
Try using inset drawables with layer-lists. Make your shadow drawable like normal, then wrap the main icon in an inset drawable. Set margins that match your shadow blur radius - this fixes the extra space the shadow creates. I did this on an e-commerce app where button sizes kept breaking the layout. The trick is getting the inset values right. Measure your shadow spread in Figma and use negative margins to pull the icon back to proper size. Works great with selectors too since you can apply the same inset logic to all states. You’ll need to tweak the measurements a bit, but once you nail it, it’s way easier to maintain than writing custom drawing code.
You could draw shadows manually, but you’ll write tons of custom code for every variation.
I hit the same wall on a project with complex UI components. Manual shadows become a nightmare when you need different colors, blur radii, or offsets.
Automation saved my sanity. I built a workflow that grabs Figma designs, pulls the exact shadow properties, and spits out Android drawables automatically. No more guessing values or fighting padding issues.
It handles layer-list creation, bounds calculation, and generates variants for different states. Processes dozens of icons in seconds instead of hours.
Set it to monitor your design files and it’ll regenerate drawables when shadows change. Your Android assets stay synced with Figma without lifting a finger.
Best part? Consistent results every time. No more sizing issues in selectors or weird padding behavior.
try using a CustomView with canvas. You can draw the shadow directly, then the icon on top. this way, it won’t mess with padding and you get the exact look you want. just need to handle drawing manually.
Had this exact issue on a banking app where icons had to look perfect. Skip drawable shadows completely - use elevation and ViewOutlineProvider instead. Set elevation on your ImageView/Button for the shadow, then create a custom OutlineProvider that matches your original icon size. This keeps the shadow separate from the drawable, so your padding won’t get messed up. The system draws shadows outside view bounds instead of baking them into the drawable. Works great with selectors since drawable dimensions stay the same. Only catch is you need API 21+, but that’s pretty much everything these days.