Creating Android button with image and text using relative layout

by Goran Siric on Monday, October 03, 2011 7:06 AM

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.

Author
Goran Siric

Blog about programming

27 comment(s) so far...

Anonymous 3/22/2012

Thank you! This is very useful!!

 
Anonymous 8/7/2012

Awesome its very interesting to know.

 
Anonymous 8/30/2012

Very nice one. But how to get text from text view

 
Goran Siric 8/30/2012

Hi udaya.Here is example of method for getting text from the text views: <br />public CharSequence getText(int id) <br />{ <br /> View v = findViewById(id);<br /> if (null != v && v instanceof TextView) <br /> { <br /> return ((TextView)v).getText(); <br /> } <br /> return ""; <br />}

 
Anonymous 11/16/2012

Simply the most comprehensive, accurate and helpful resource for using images for button layouts with Android, seriously.<br /><br />Many blogs/forums/posts often quote inaccurate, hacky and in-concise solutions but your blog gets straight to the point with great (simple) examples - definitely helped me out!

 
Anonymous 4/17/2013

Hi can you please tell how to have multi line text with different color in a button??

 
Goran Siric 4/23/2013

Hy babar,<br />you can add following code to RelativeLayoutButton class to support differnent colors of text on button:<br /><br />public void setTextColor(int id, int color)<br /> {<br /> View v = findViewById(id);<br /> if (null != v && v instanceof TextView)<br /> {<br /> ((TextView)v).setTextColor(color);<br /> }<br />}<br /><br />and then from your main code you can set text color of specific text on button using following code:<br /><br /> button3.setTextColor(R.id.test_button_text2, Color.BLUE);<br /><br />

 
Anonymous 4/25/2013

Dude, that was really helpful. Thanks!!

 
Anonymous 2/18/2014

Thank you very much!

 
Anonymous 3/13/2014

hi..<br />You have added star as your icon in the button. When you store image in drawable folder it will be always in rectangle shape . I am getting rectangle ugly icon in the button. <br />So how to create icon like star ?

 
Goran Siric 3/13/2014

Your icon must have transparent background. It's best to save icon in .PNG format with transparent background.

 
Anonymous 3/31/2014

awesome example and easy to follow. how do I set button states such as on button pressed, button focused and change the background color?

 
Goran Siric 3/31/2014

In code I am using:<br /><br /> Button bt = new Button(context);<br /> this.setBackgroundDrawable(bt.getBackground());<br /><br />to set drawable background for button. This way button looks like standard android button.<br />You can call setBackgroundDrawable() in code to change current button drawable(states).<br />If you want to set background drawable in xml resource files, then you can sliglty change code to not use this two lines of code if background drawable is allready set.<br />

 
Anonymous 6/1/2014

Why don't you just formulate your XML like this<br /><br /><br /> <br /> android:layout_width="wrap_content"<br /> android:src="@drawable/icon"<br /> android:layout_height="wrap_content"<br /> android:layout_alignParentTop="true"<br /> ImageView><br /> <br /> TextView><br /> <br /> TextView><br /><br /><br />include like this<br /><br /><br />include><br /><br />and find it like this<br /><br />RelativeLayoutButton button1 = (RelativeLayoutButton)this.findViewById(R.id.button1);<br />

 
Anonymous 6/1/2014

Never mind, I can't post suffice it to say, you are doing it the hard way.

 
Anonymous 8/22/2014

Maybe a noob question but how can center the text and images within the button?

 
Anonymous 1/30/2015

Hi, nice example i had one doubt, how to show image in a button with text show in a same button , can u help me i am fresher in android ,<br />and i need 8 image button in home how it done .

 
Goran Siric 1/30/2015

Hi sudhakar,<br />can you explain a little bit more what exactly you need.

 
Anonymous 6/1/2015

Hi, <br /> This suresh i want to know how to write code for image cum text buttons in android and also it should be in round shape.could you please explain about this.

 
Anonymous 10/25/2015

Very useful. Thank you very much.

 
Anonymous 2/17/2016

Thanks buddy..,<br />That was very helpful to learn about relative layout.

 
Anonymous 2/17/2016

Please create a xml file and give the shape as round or oval and give the source to the element, say it as button and thats it...<br />For ex:<br />In xml file say rounded.xml in relevant drawable folder<br /><br /><br />and in any of the layout file and say the button as<br /><br /><br />thats it..,<br />Hope you will check this..<br />Have fun happy coding...<br />Cheers.

 
Anonymous 4/22/2016

Hello, I am new for android.I want to move text on image view. how its possible?<br />Plz help me.Thanks in advance

 
Anonymous 8/23/2016

Hi dude, i have also find out one good example <br /><a href="http://androidexample.com/How_To_Create_Button_Android_Example/index.php?view=article_discription&aid=47&aaid=72" rel="nofollow"><br />How To Create Button<br /></a><br />

 
Anonymous 9/28/2016

Hi bro,<br /><br />Can u tell me how to set the size of icon according to our requirement in button ?<br /><br />Actually my icon size is 256x256 and i want 20x20 ???

 
Goran Siric 9/29/2016

Hi Shameel,try to use ImageView android:scaleType property in xml button layout:<br /><br /> android:scaleType="centerInside"<br /><br />For more info see: <a href="https://developer.android.com/reference/android/widget/ImageView.ScaleType.html" rel="nofollow">developer.android.com/reference/android/widget/ImageView.ScaleType.html</a>

 
Anonymous 3 months ago

What if, using the drawable left method, i want to increase the distance of the icon from the left limit of the button, making it a bit more central?



  Hi folks! I am proud to present: 
Bubble Zoo Escape, my first Android game built using AndEngine 
If you have a time, please download and give feedback!

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

By me a coffe through PayPal :)


Featured articles

AndEngine - Textures tips and tricks

What you should know abot textures before get started programming your first game.

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.

Copyright 2011 by Goran Siric