The power of TextView (Part 1): Drawables

TextViews are one of the basis of Android UI framework. Buttons, EditTexts, RadioButtons are, indeed, TextViews. And they are also one of the most powerful tools we have to create our layouts. Knowing them in deep can help us save time, views and simplify our layouts, making our UI faster.

In this series, I will talk about TextView and its direct subclasses. I’m beginning with one of the most basic cases, that you may know. But If you don’t, you will love it.

There are a lot of situations where we need to use a TextView (or EditText, Button… remember they are subclasses) with a simple image at the left or right. That’s not that difficult, right? We simply need an ImageView plus a TextView inside a LinearLayout:

Textview with drawable

[xml]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal"
android:gravity="center"
android:layout_gravity="center_horizontal"
>
<TextView
android:text="@string/my_contacts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:paddingLeft="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_add_group"
/>
</LinearLayout>
[/xml]

Lint already warns that there is a better way to do this by using a TextView and a compound drawable. What’s this? Our TextView has four properties that let us specify images to be set around it. These ones are: drawableLeft, drawableRight, drawableTop and drawableBottom. We also can use another one which defines the padding among the text and the images: drawablePadding.

Ok then, let’s change the previous layout and get rid of LinearLayout and ImageView:

[xml]
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"
android:layout_gravity="center_horizontal"
android:text="@string/my_contacts"
android:drawableRight="@drawable/ic_action_add_group"
android:drawablePadding="8dp"
/>
[/xml]

Cool! We removed a level of complexity and made our XML much simpler. It’s almost as easy to set these drawables from code:

[java]
textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_add_group, 0);
textView.setCompoundDrawablePadding(…);
[/java]

With this idea in mind, we can create very interesting layouts. Let’s create a simple username and password form:

Simple form

[xml]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:orientation="vertical"
android:layout_marginTop="16dp"
>

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:hint="@string/user_name"
android:drawableLeft="@drawable/ic_action_person"
android:drawablePadding="8dp"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:hint="@string/password"
android:drawableLeft="@drawable/ic_action_accounts"
android:drawablePadding="8dp"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/log_in"
android:drawableRight="@drawable/ic_action_accept"
/>

</LinearLayout>
[/xml]

Quite easy. Next episode will cover a way to make a drawable clickable, another trick to keep your layout simple by taking the most out of TextViews.

22 thoughts on “The power of TextView (Part 1): Drawables”

  1. Good post.
    But we have to keep in mind that these can only be useful in certain scenarios.
    For example if we want to have a drawable at the start of a multiline textview it wont be possible unless you are targetting API 17.

  2. ¿Has probado a hacerlo en un Navigation Drawer con un custom adapter? No funciona bien, al menos a mí me hace cosas raras (a partir del tercer elemento repite todos los compounds drawables aunque las asignaciones sean distintas….)

  3. Hello,

    You never wrote a part II to this. I am looking for a way to add click events to a text views drawables

    1. EDIT: I have checked SO. A neat trick is to add an onTouchListener to the TextView and check if the motion even fals within the bounds of the drawable. The theory looks solid so I’ll try that out later.

      New challenge: Draw a drawable based on its state…The problem here is that I have a custom drawable that is set as a TextView compoundDrawable. How can I draw my drawable based on the pressed state (I can andle the clicks with the above manner, I just need visual indication that the drawable has been pressed)

Comments are closed.