I’m working on a custom View in Android using Kotlin and I want to add an inset shadow effect to a circular shape, similar to what you can do in design tools like Figma.
I’ve experimented with using BlurMaskFilter with Blur.INNER setting and tried adjusting the shadow position using canvas.translate(), but the outcome isn’t quite what I’m looking for. The shadow doesn’t look as smooth or realistic as I need it to be.
What would be the most effective approach to create a convincing inset shadow on circular shapes in Android? Are there better alternatives to BlurMaskFilter? Should I consider using gradient overlays instead? I’m open to any technique that can produce a professional-looking inner shadow effect.
Any help or code examples would be really helpful!
Here’s what worked for me: use canvas layers with different blend modes. Draw your base circle first, then add a slightly darker version on a separate layer - position it 2-3 pixels inward from the edge. Use Paint.setColorFilter with ColorMatrixColorFilter to darken just the shadow part. Instead of one thick shadow, draw multiple thin rings. Much better control that way. Make each ring less opaque as you go inward. This beats gradients because you can tweak shadow width and intensity at runtime without rebuilding everything. Performance stays solid since you’re just drawing basic shapes with different alpha values.
I’ve dealt with this exact problem. Custom shadows using Path clipping work way better than other methods. Draw your circle, then create a second Path that’s slightly smaller and offset toward your light source. Use canvas.clipPath with Region.Op.DIFFERENCE to create the shadow area, then fill it with semi-transparent paint. The trick is multiple passes with decreasing opacity - usually 3-4 layers with alpha values like 30, 20, 15, 10. Offset each layer by 1-2 pixels. You get precise control over shadow direction and intensity without the performance hit from blur operations. Works great when you need consistent results across different devices.
Had this same issue a few months back. Here’s what worked for me: skip BlurMaskFilter and draw multiple concentric circles instead. Each circle gets gradually lower alpha and slight position offsets. Use RadialGradient - transition from your shadow color to transparent, then clip it inside the circle boundary. Paint.setXfermode with PorterDuff.Mode.MULTIPLY blends the shadow way better with whatever’s behind it. For gradient stops, don’t go linear - use 4-5 stops with exponentially decreasing alpha. Makes the depth look way more realistic than standard blur filters. Performance’s been fine even with multiple circular views running.
Use elevation with ViewOutlineProvider - much easier than custom drawing. Set your view’s outline to a circle, then bump up the elevation for depth. Add a custom drawable with a subtle radial gradient from center to edges. Way less code and Android handles the shadow rendering automatically.
gradient overlays are def your best bet. i create a radial gradient from dark to trans and mask it - way smoother than blur filters. use ComposeShader to combine your base circle with the shadow gradient. gives way better control over the falloff.
This topic was automatically closed 4 days after the last reply. New replies are no longer allowed.