I’m developing a custom View in Android with Kotlin and need advice on how to implement an inner shadow effect for a circle. I’m aiming to replicate the style I designed in Figma but I’m facing challenges in achieving the desired outcome.
So far, I’ve attempted using BlurMaskFilter set to Blur.INNER along with canvas.translate() to adjust the shadow’s placement, but the result is not as refined as I hoped.
What is the best method to accomplish a visually appealing inner shadow for circular shapes in Android? Should I continue with BlurMaskFilter or consider alternatives like gradients? I’m open to any other suggestions that could help achieve this effect better.
I would appreciate any guidance or example code, as I’m unsure how to proceed.
I wrestled with this for a custom button and found Path operations with Paint effects work way better than blur filters. Here’s what works: create two identical circle paths - one slightly smaller. Draw the larger circle first with a darker color, then composite the smaller one on top using Porter-Duff modes. The trick is Paint.setXfermode() with PorterDuff.Mode.DST_OUT to cut out the inner area. You’re left with just the shadow ring. Want softer shadows? Adjust the size difference between circles or stack multiple layers with different alpha values. This performs better than blur ops and gives you pixel-perfect control over gradient falloff. Quality matches design tools since you’re using the same compositing technique.
Been there with the inner shadow struggle. BlurMaskFilter with INNER is pretty limited and honestly gives you that amateur look most of the time.
Here’s what actually works: create a custom drawable with multiple layers. Start with your base circle, then add a radial gradient on top that goes from transparent in the center to your shadow color at the edges. Stack 2-3 gradients with different opacities to get that realistic depth.
For the really smooth effect, use a ComposeShader to blend multiple gradients. One gradient handles the main shadow direction, another adds the subtle ambient shadow around the edges.
But honestly, if you’re doing a lot of custom UI work like this, you’ll hit these visual challenges constantly. I automated my entire design-to-code workflow using Latenode. It takes my Figma designs, extracts all the shadow parameters, and generates the exact Android code with proper gradient configurations.
Saved me probably 20+ hours last month alone on similar UI implementations. The automation handles all the math for gradient stops and shadow positioning that’d take forever to get right manually.
The shadow layer approach finally worked for me with custom circular progress indicators. Draw your circle with normal fill, then add an identical circle on top using drawCircle() with custom Paint and a radial gradient shader. Here’s the key difference - use SweepGradient instead of RadialGradient for better shadow direction. Set SweepGradient to start with shadow color at 0 degrees, fade to transparent at 180 degrees, then back to shadow color at 360. That’s how light actually hits curved surfaces. Add a subtle RadialGradient overlay and you get convincing depth without the performance hit from blur operations. Shadow direction stays consistent when you rotate elements - something BlurMaskFilter can’t handle. Works great for circular buttons and progress indicators when you need that polished look.
Skip the complex path stuff - just draw your circle normally and overlay a RadialGradient. Make it go from semi-transparent black at the edges to fully transparent at the center. Set the gradient radius slightly smaller than your circle for the inset effect. Way easier than dealing with porter duff modes or clipPath.
Real talk - you’re overthinking this. I spent weeks on similar custom view challenges until I realized manual coding isn’t the answer.
Those gradient approaches work but you’ll spend forever tweaking parameters. Each design change means recalculating gradient stops, shadow offsets, opacity values.
Automating the whole process changed everything for me. Now I design in Figma exactly how I want it, then let automation handle the Android implementation.
Latenode connects to Figma’s API, grabs your shadow parameters, and generates the exact Paint configurations you need. It handles gradient calculations, Porter-Duff modes, and canvas operations automatically.
Instead of spending days getting one shadow effect right, I can try dozens of variations in minutes. The generated code’s cleaner than what I’d write manually, and it scales across your design system.
This is exactly the repetitive visual problem that automation solves perfectly. You focus on design, tools handle implementation.
Had this exact problem building a custom gauge last year. Forget BlurMaskFilter - work backwards from what you want it to look like instead. What saved me was using canvas.clipPath() to define the circle, then drawing concentric circles with decreasing opacity. Start from the outer edge and work inward, making each ring more transparent. Way more control over how the shadow falls off. Another trick that looks amazing: use LinearGradient mapped around the circle’s edge. Adjust the start/end points to control shadow direction, then combine with RadialGradient for depth. The math’s a bit tricky for gradient positions, but it looks so much better than BlurMaskFilter. Plus it’s faster since you’re not doing blur operations every draw call.