Creating Android button with image and text using relative layout

Oct 3

Written by: Goran Siric
10/3/2011 3:06 PM  RssIcon

If you just want to create basic button with image and text on it, you can use standard android button control and one of the following properties: drawableLeft, drawableRight, drawableTop, drawableBottom.

If you want to get button like this:

You can use the drawableLeft property of Button control to set image which will be displayed to the left side of the text.

Here is the code:

<Button
 android:id="@+id/button1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:drawableLeft="@android:drawable/btn_star_big_on"
 android:text="Drawable left">
Button>


In the similar way you can use drawableRight, drawableTop, drawableBottom properties to create buttons with image right, top or bottom to the text. 

 
If you want to have two lines of text you can use \n (line feed) character to divide text into two or more lines. 

For button like this:

 you need to use following code:

<Button
 android:id="@+id/button3"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:drawableLeft="@android:drawable/btn_star_big_on"
 android:text="Drawable\nleft">
Button>


Notice that in eclipse design view you will not see button with text in two lines. Instead you will see image like this:

Don't wory about that. When you run your application text will be rendered in two lines.


Similarly, if you for example want button with 4 lines of text:

you  can use following code:

<Button
 android:id="@+id/button4"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:drawableLeft="@android:drawable/btn_star_big_on"
android:text="Drawable\nleft\nfour\nlines">
Button>


There are few more properties of button which can be used to style your button.  DrawablePadding property can be used to set spacing between text and the image, while Gravitiy property can be used to align text left or rigth.

Here is example of button with DrawablePadding  property set to 10dp and Gravity property set to left:

Code for this button is:

<Button
 android:id="@+id/button6"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:drawableLeft="@android:drawable/btn_star_big_on"
 android:text="Drawable\nleft\ngravity\nleft"
 android:gravity="left"
 android:drawablePadding="10dp">
Button>

All previous examples have one disadvantage. You cannot have different font style and size for each line of text. If you really want complex button like that, here is solution I made. I like how it's nice to use  RelativeLayout to define complex layouts, and  I decided to try to create Button which layout can be defined with RelativeLayout.


I tried to make solution simple and  easy to use. Here is the result, give it try. 

Full source code can be downloaded here: RelativeLayoutButton.zip

Creating button layout using RelativeLayout

First what you need is to create new Android XML RelativeLayout file. It will served as a template for our Button. 

Here is example of button layout which consists of one ImageVew and two TextView controls: 

test_button.xml

<xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
   android:layout_height="wrap_content" android:layout_width="wrap_content">
    <ImageView
      android:id="@+id/test_button_image">
      android:layout_width="wrap_content"
      android:src="@drawable/icon"
      android:layout_height="wrap_content"
      android:layout_alignParentTop="true"
    ImageView>
    <TextView
      android:id="@+id/test_button_text2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textSize="20sp"
      android:layout_alignTop="@+id/test_button_image"
      android:layout_toRightOf="@+id/test_button_image"
      android:text="Relative layout">
   TextView>
   <TextView
      android:id="@+id/test_button_text1"
      android:layout_width="wrap_content"
      android:text="Compound button"
      android:layout_height="wrap_content"
      android:layout_below="@+id/test_button_text2"
      android:layout_alignLeft="@+id/test_button_text2">
   TextView>
RelativeLayout>

Here is the graphical result of test_button.xml:

Using test_button.xml layout in other layouts

To reuse button layout in other XML layouts simply use include tag in other layouts. There are two important attributes of include  tag: layout and android:id  Layout attribute represents name of layout to include, while android:id represents Id which will be used to access button in our code.

Here is example of main.xml  layout which consists of three buttons. Also notice that every include tag have different layout attributes. They define Buttons position in parent view.

main.xml

xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />
<include android:id="@+id/button1"
   layout="@layout/test_button"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content">
include>
<include android:id="@+id/button2"
   layout="@layout/test_button"
   android:layout_height="wrap_content"
   android:layout_width="wrap_content"
   android:layout_gravity="center">
include>
<include android:id="@+id/button3"
   layout="@layout/test_button"
   android:layout_height="wrap_content"
   android:layout_width="wrap_content">
include>
LinearLayout>


Here is graphical representation of main.xml:

RelativeLayouButton  class

Here is the source code of RelativeLayoutButton class. Constructor accept context and id of RelativeLayout which will serve as template for our button. Comments are in code:

package relativelayoutbutton.android.izvornikod.com;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
 
 
public class RelativeLayoutButton extends RelativeLayout {
     
      public RelativeLayoutButton(Context context, int id)
      {
            super(context);
 
            // if our context is not Activity we can't get View supplied by id
            if (!(context instanceof Activity))
                return;
 
            // find relative layout by id  
            View v = ((Activity)context).findViewById(id);
             
            // is it RelativeLayout ?
            if (!(v instanceof RelativeLayout))
                return;
 
            //cast it to relative layout
            RelativeLayout layout = (RelativeLayout)v;
                         
            // copy layout parameters 
            ViewGroup.LayoutParams params = layout.getLayoutParams();
            this.setLayoutParams(params);
              
            // here I am using temporary instance of Button class
            // to get standard button background and to get button text color
 
            Button bt = new Button(context);
            this.setBackgroundDrawable(bt.getBackground());
             
            // copy all child from relative layout to this button
            while (layout.getChildCount() > 0)
            {
                 View vchild = layout.getChildAt(0);
                 layout.removeViewAt(0);
                 this.addView(vchild);
                  
                 // if child is textView set its color to standard buttong text colors
                 // using temporary instance of Button class
                 if (vchild instanceof TextView  )
                 {
                    ((TextView)vchild).setTextColor(bt.getTextColors());
                 }
                  
                 // just to be sure that child views can't be clicked and focused
                 vchild.setClickable(false);
                 vchild.setFocusable(false);
                 vchild.setFocusableInTouchMode(false);
             }
              
             // remove all view from layout (maybe it's not necessary)
             layout.removeAllViews();
              
             // set that this button is clickable, focusable, ...
             this.setClickable(true);
             this.setFocusable(true);
             this.setFocusableInTouchMode(false);
          
             // replace relative layout in parent with this one modified to looks like button
             ViewGroup vp = (ViewGroup)layout.getParent();
             int index = vp.indexOfChild(layout);
             vp.removeView(layout);
             vp.addView(this,index);
              
             this.setId(id);
              
      }
       
      // method for setting texts for the text views
      public void setText(int id, CharSequence text)
      {
          View v = findViewById(id);
          if (null != v && v instanceof TextView)
          {
              ((TextView)v).setText(text);
          }
           
      }
      // method for setting drawable for the images
      public void setImageDrawable(int id, Drawable drawable)
      {
           
          View v = findViewById(id);
          if (null != v && v instanceof ImageView)
          {
              ((ImageView)v).setImageDrawable(drawable);
          }
           
      }
       
      // method for setting images by resource id
      public void setImageResource(int id, int image_resource_id)
      {
           
          View v = findViewById(id);
          if (null != v && v instanceof ImageView)
          {
              ((ImageView)v).setImageResource(image_resource_id);
          }
           
      }
 
}


To use button in the code you first must create instance of the RelativeLayoutButton. Instance must be created in Activity class, usually in onCreate method. After that you can attach event handlers to it and modify text and images on the button using methods of RelativeLayoutButton class.

Here is example of using RelativeLayoutButton :

package relativelayoutbutton.android.izvornikod.com;
 
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RelativeLayout;
import android.widget.Toast;
 
public class RelativeLayoutButtonActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         
        RelativeLayoutButton button1 = new RelativeLayoutButton(this,R.id.button1);
       
        button1.setOnClickListener( new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(RelativeLayoutButtonActivity.this, "RelativeLayoutButton clicked", Toast.LENGTH_LONG).show();
                 
            }
        });
         
        RelativeLayoutButton button2 = new RelativeLayoutButton(this,R.id.button2);
        button2.setText(R.id.test_button_text1, "Change");
        button2.setText(R.id.test_button_text2, "text");
         
        RelativeLayoutButton button3 = new RelativeLayoutButton(this,R.id.button3);
        button3.setText(R.id.test_button_text1, "Change");
        button3.setText(R.id.test_button_text2, "image");
        button3.setImageResource(R.id.test_button_image, android.R.drawable.star_big_on);
         
    }
}


Started activity look like on the image below. 

Full source code can be downloaded here: RelativeLayoutButton.zip

Feel free to leave comments.

1 comment(s) so far...


Gravatar

Re: Creating Android button with image and text using relative layout

Thank you! This is very useful!!

By Nice on   3/22/2012 11:13 PM

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment   Cancel 

Search Blog

If you found this useful,
you can buy me a coffe :)

By me a coffe through PayPal :)

Featured articles

Android "DataEntry ListView" Design Pattern

Have you realized the importance of ListView control in developing android applications ?

GIMP script for creating Android icons at once

Script for creating Android icons for different screen resolutions at once. Icons can be saved using standard Android icons naming conventions and saved in appropriate folders.

Creating Android button with image and text using relative layout

Source code with examples how to use relative layout to create nice buttons with text and images in Android

Android application and the Internet

Tutorial about connecting to the web pages on the Internet from Android application, using both POST and GET web requests.

Recent Entries

Comments about Parking SMS Scheduler
Comments about cities and parking zones
Android "DataEntry ListView" Design Pattern
Android application and the Internet
Keep my DNN site alive
Android default icons

Recent Comments

Re: Creating Android button with image and text using relative layout
Thank you! This is very useful!!
Re: GIMP script for creating Android icons at once
sorry for writing in English I am French but I vien to find thanks to google finally information on the subject that I currently work thank you for sharing good information thanks to you I will advance 'll see you soon I'll follow you to the next and I recommend reading your blog friendly
Great Info.
Great information you got here. I've been reading about this topic for one week now for my papers in school and thank God I found it here in your blog. I had a great time reading this.
Re: GIMP script for creating Android icons at once
Thank you for supporting me :)
Re: GIMP script for creating Android icons at once
Thank you so much! Have donated some money to you so you can buy yourself a good beer.
You deserve it!