Text Shadows

Often tools like Photoshop are used to create graphic elements which are actually text with various effects applied to them, and an well used effect in such elements is the use of shadows. Android supports text shadows, and in this article we’ll explore a number of ways that we can use the built in shadows as it is much more efficient to use TextView than it is to include lots of bitmap elements for our text; it also makes designing for multiple screens much easier, as well, because the Android layout manager can scale TextView elements much easier than the bitmaps in ImageView objects.

Text shadows require four parameters:

  1. The shadow colour: what colour the shadow will be
  2. The X offset: where the shadow is positioned horizontally relative to the text
  3. The Y offset: where the shadow is positioned vertically relative to the text
  4. The radius: How much the edges of the shadow will be blurred

Text shadows are something of a misnomer because we can actually achieve some effects that bear absolutely no resemblance to a shadow as we shall see later. However, let’s start with a simple example which does resemble a shadow:

<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" 
	android:background="@color/White"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:textColor="@color/Black"
		android:layout_width="wrap_content"
		android:text="Simple Shadow"
		android:layout_height="wrap_content" 
		android:padding="2dp"
		android:shadowColor="@color/TransparentGrey" 
		android:shadowDx="3"
		android:shadowDy="3" 
		android:shadowRadius="0.01" />
</LinearLayout>

There are a couple of support files which define our colours which we’ll use throughout this article. These are res/values/colours.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<color name="White">#FFF</color>
	<color name="Black">#000</color>
	<color name="Grey">#7F7F7F</color>
	<color name="DarkGrey">#4F4F4F</color>
	<color name="Green">#0F0</color>
	<color name="TransparentGrey">#7F000000</color>
</resources>

and res/drawables/gradient.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
	<gradient 
		android:startColor="@color/White" 
		android:endColor="@color/Black" 
		android:angle="0"/>
</shape>

If we run this, well see our text with a simple drop shadow:

There is one aspect of how shadows work which can cause some problems: The shadow radius must always be present, and it cannot be ’0′ otherwise the shadow will not be drawn. In this example, I want a hard edge to the shadow so I have to put the radius to a tiny number to achieve this.

So, this example creates a simple grey shadow which is offset from the text by 3 pixels in each direction, and has an infinitesimally small radius which gives us a hard edge to the shadow.

We can soften the edge of the shadow by increasing the radius:

<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" 
	android:background="@color/White"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:textColor="@color/Black"
		android:layout_width="wrap_content"
		android:text="Soft Shadow"
		android:layout_height="wrap_content" 
		android:padding="2dp"
		android:shadowColor="@color/TransparentGrey" 
		android:shadowDx="3"
		android:shadowDy="3" 
		android:shadowRadius="1.5" />
</LinearLayout>

And this gives us:

Another thing that we can do is to change the offsets to effectively change direction of the light source:

<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" 
	android:background="@color/White"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:textColor="@color/Black"
		android:layout_width="wrap_content"
		android:text="Soft Shadow (Below)"
		android:layout_height="wrap_content" 
		android:padding="2dp"
		android:shadowColor="@color/TransparentGrey" 
		android:shadowDx="3"
		android:shadowDy="-3" 
		android:shadowRadius="1.5" />
</LinearLayout>

This gives us:

There is another effect which is extremely widespread at the moment, and that it to give text an “engraved” look, and this works particularly well against grey or metallic backgrounds. We can achieve this by using a white shadow with a small blur, and only a small offset from the text:

<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" 
	android:background="@color/Grey"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:textColor="@color/Black"
		android:layout_width="wrap_content"
		android:text="Engraved Shadow"
		android:layout_height="wrap_content" 
		android:padding="2dp"
		android:shadowColor="@color/White" 
		android:shadowDx="1"
		android:shadowDy="1" 
		android:shadowRadius="0.6" />
</LinearLayout>

It looks like this:

Another way we can use shadows it to create glow effects by using X and Y offsets of 0, a largish blur and a shadow colour which matches the text colour:

<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" 
	android:background="@color/Black"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:textColor="@color/White"
		android:layout_width="wrap_content"
		android:text="Glowing Text"
		android:layout_height="wrap_content" 
		android:padding="2dp"
		android:shadowColor="@color/White" 
		android:shadowDx="0"
		android:shadowDy="0" 
		android:shadowRadius="3" />
</LinearLayout>

Which gives us:

We can also use a shadow to provide us with an outline glow by setting the text colour to match the background of the parent, and using a contrasting shadow with X and Y offsets of 0:

<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" 
	android:background="@color/Black"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:textColor="@color/Black"
		android:layout_width="wrap_content"
		android:text="Ethereal Text"
		android:layout_height="wrap_content" 
		android:padding="2dp"
		android:shadowColor="@color/White" 
		android:shadowDx="0"
		android:shadowDy="0" 
		android:shadowRadius="2" />
</LinearLayout>

It looks like this:

By simply changing the shadow colour, we can also change the feel of the glow effect:

<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" 
	android:background="@color/Black"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:textColor="@color/Black"
		android:layout_width="wrap_content"
		android:text="Spooky Text"
		android:layout_height="wrap_content" 
		android:padding="2dp"
		android:shadowColor="@color/Green" 
		android:shadowDx="0"
		android:shadowDy="0" 
		android:shadowRadius="2" />
</LinearLayout>

Which gives us:

Finally, let’s consider a rather practical issue. Sometimes when using text over a background which is either a gradient, or even a busy background bitmap drawable the text stands out perfectly well in some places, but gets lost in the background in others. Here is a simple example:

The text is easy to read on the left, but as we get further right where the background colour gets nearer to the text colour, we begin to lose the text in the background and it becomes more difficult to read. Let’s create a glow effect of a contrasting colour to the text:

<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" 
	android:background="@drawable/gradient"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:textColor="@color/Black"
		android:layout_width="wrap_content"
		android:text="This is text which gets lost in the background"
		android:layout_height="wrap_content" 
		android:textStyle="bold"
		android:padding="2dp"
		android:shadowColor="@color/White" 
		android:shadowDx="0"
		android:shadowDy="0" 
		android:shadowRadius="0.7" />
</LinearLayout>

This helps the text to stand out when the background colour is similar to the text colour:

One final point which is certainly worth making is that just because you have learned a new technique does not mean that you should use it everywhere! Applying these kinds of effects to a block of body text will render it more difficult to read. Confine fancy effects to headers, and standalone blocks of text.

ADDENDUM: +Kirill Grouchnikov makes an excellent point in this post: Android does not make the bounding box larger when adding text shadows. All of the examples in this article have android:padding=”2dp” set otherwise the shadow may be clipped. Shadows with a large radius, or a large offset may require more padding to prevent clipping.

The source code for this article can be found here.

© 2011, Mark Allison. All rights reserved. This article originally appeared on Styling Android.

Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License

Send the author to the moon!

Creative Commons License
Text Shadows by Styling Android, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Terms and conditions beyond the scope of this license may be available at blog.stylingandroid.com.

Tags: ,

14 Responses to “Text Shadows”

  1. srihari babu says:

    good job

  2. Lars Hesel says:

    Hi Mark

    In the last example, in the LinearLayout, you refer to the @color/black as background, I suspect you wanted that to be @drawable/gradient.

    Thanks for a lot of great quality, in-depth articles! Lot’s of stuff to learn, even for seasoned android developers.

    Cheers,
    Lars

  3. Mark Allison says:

    Hi Lars,

    Thanks for the feedback.

    The code on github.com was correct, but I must have had a cut & paste error. D’Oh!

    All fixed now.

    Cheers,

    Mark

  4. Isneesh Marwah says:

    Hello,

    Just had one question regarding text shadows : I want to change the text shadow, depending on the different states of the elements like buttons, tabs etc. Eg, I would like to have different colours/shadows of the font for the pressed state of a button and normal state of the same.

    I am able to achieve different colours by using a colour state list, but can’t seem to figure out a way to do the same for shadows.

    Any idea?

  5. mohammad says:

    hi
    how do i get background color of TextView?

  6. Jorge says:

    Excelent!! espero que me sirva en un futuro, Thanks!

  7. mohan says:

    hey ,
    good job man..

  8. Elica says:

    That was so useful. Thanks a lot :)

  9. Henrik says:

    Nice tutorial :)
    Thanks!

  10. bala says:

    Can you explain how to make gradient Text color?

  11. sunita says:

    Its really very helpful.

  12. Deepak Swami says:

    great tutorial..

  13. Max says:

    Hi i’m new in android but i will use the shadow but don’t work.

    This is my code: http://www.hg-hdro.de/mycode.txt

    Thanks for help

Leave a Reply