Take control of view’s shadow — Android

You can find updated code that is written in Kotlin here

Arman Soudi
4 min readApr 23, 2017

--

Let’s say you’re looking for how to implement shadow on your View in Android and you are going to Google something. You will probably find these 3 answers.

We are going to check these answers, and after we check them all I will suggest new way that you can implement shadow in any View you want.

Use drawable with multi different color solid (worse thing that you can do)

Just use 5–6 shapes that have padding, and at the end the shape that will be your view’s main background, those shapes will be overlapping on each other and Baam! you have drop shadow

Let’s see the result. Yes for some people this one is acceptable (not for me), but let’s enable Debug GPU Overdraw and check result too

Reason we have awful overdraw is that those shapes we used for creating shadow

4x+ Overdraw it’s not good, so never ever ever ever use this solution, not worth it.

Android elevation (supported from API 21)

It’s easy to use, just add one attribute to your view’s XML or even enable it with Java code in your View class check Android documentation

The result is perfect, overdraw is acceptable but you older APIs will not support this shadow

Let’s check overdraw and the result.

Do you see that green border on left|top|right of overdraw result that means some part of view overdraw 2x time I have no idea why this is happening.

CardView

When you are using CardView you will see shadow in all APIs, but the result in older APIs are not same as 21+ APIs

Cardview overdraw is exactly same as elevation

But there is one thing you should know; if you go to CardView source code you will notice that CardView extends from FrameLayout (link), That means if you want to use LinearLayout as Parent View it will add inside of Framelayout, so you will always have one more extra overdraw in your views. And when you are using CardView (Elevation) you can not change the shadow’s color, you can not change the shadow’s direction (top|left, bottom|right) you need to follow material design in your application.

Using Shape Drawable (New way to implement shadow)

Why not create the shadow ourself? You need to create a custom view and initial in background.

I found this when I decided to implement a dynamic background for my custom view.

First, let’s see the result.

The result is same as CardView, we don’t have that green 2x overdraw and you can use it in any view you want and you can control your shadow’s direction and color.

Here is just a simple example how it works.

You can add this view in your XML and you have LinearLayout that support rounded box with drop shadow.

You can create your own attribute and pass background color, corner radius, shadow color through XML too.

And the good part is you are not forced to use FrameLayout as your parent view, you can easily create any view you want.

Let’s go to ViewUtils class and see magical things.

This function generate shadow with 3 different direction with custom radius and color.

First, we create background paint to draw our background color and we will add shadow layer with only corner radius that we want.

Next, we add padding to shape drawable to prevent overlapping view’s content on the shadow layer.

With ‘setShadowLayer’ you can change the color of shadow and also the direction of shadow and after that, you need to add a corner to your shadow layer too.

And at the end we merge it to LayerDrawable and set Inset to drawable for not seeing cutting shadow, that’s all.

Result with Top shadow direction and blue shadow color

It’s just simple example,you can use more that one ShapeDrawable to create customizable shadow.

In the next post, I will show how you can clip shape in view with shadow background.

Cheers.

--

--