Thursday, May 31, 2012

Android: combining text & image on a Button or ImageButton


I'm trying to have an image (as the background) on a button and add dynamically, depending on what's happening during run-time, some text above/over the image.



If I use ImageButton I don't even have the possibility to add text. If I use Button I can add text but only define an image with android:drawableBottom and similar XML attributes as defined here .



However these attributes only combine text & image in x- and y-dimensions, meaning I can draw an image around my text, but not below/under my text (with the z-axis defined as coming out of the display).



Any suggestions on how to do this? One idea would be to either extend Button or ImageButton and override the draw()-method. But with my current level of knowledge I don't really know how to do this (2D rendering). Maybe someone with more experience knows a solution or at least some pointers to start?



Thanks


Source: Tips4all

7 comments:

  1. You can call setBackgroundDrawable() on a Button to set the background of the button.

    Any text will appear above the background.

    If you are looking for something similar in xml there is:
    android:background attribute which works the same way.

    ReplyDelete
  2. For users who just want to put Background, Icon-Image and Text in one Button from different files: Use background, drawableTop/Bottom/Rigth/Left and padding Attributes.

    <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/home_btn_test"
    android:drawableTop="@drawable/home_icon_test"
    android:textColor="#FFFFFF"
    android:id="@+id/ButtonTest"
    android:paddingTop="32sp"
    android:drawablePadding="-15sp"
    android:text="this is text"></Button>


    For more sophisticated arrangement you also can use RelativeLayout and make it clickable. Here you get an idea how to arrange things with it.

    ReplyDelete
  3. For everybody who find this thread for a solution for this problem: There is a much better solution.

    Just take a normal Button and use the drawableLeft and the gravity attributes.

    <Button
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:drawableLeft="@drawable/my_btn_icon"
    android:gravity="left|center_vertical" />


    This way you get a button which displays a icon in the left side of the button and the text at the right site of the icon vertical centered.

    ReplyDelete
  4. <Button android:id="@+id/imeageTextBtn"
    android:layout_width="240dip"
    android:layout_height="wrap_content"
    android:text="Side Icon With Text Button"
    android:textSize="20sp"
    android:drawableLeft="@drawable/left_side_icon"
    />

    ReplyDelete
  5. I took a different approach from the ones stated here, and it is working really well, so I wanted to share it.

    I'm using a Style to create a custom button with image at the left and text at the center-right. Just follow the 4 "easy steps" below:

    I. Create your 9 patches using at least 3 different PNG files and the tool you have at: /YOUR_OWN_PATH/android-sdk-mac_x86/tools/./draw9patch. After this you should have:

    button_normal.9.png, button_focused.9.png and button_pressed.9.png

    Then download or create a 24x24 PNG icon.

    ic_your_icon.png

    Save all in the drawable/ folder on your Android project.

    II. Create a XML file called button_selector.xml in your project under the drawable/ folder. The states should be like this:

    <item android:state_pressed="true" android:drawable="@drawable/button_pressed" />
    <item android:state_focused="true" android:drawable="@drawable/button_focused" />
    <item android:drawable="@drawable/button_normal" />


    III. Go to the values/ folder and open or create the styles.xml file and create the following XML code:

    <style name="ButtonNormalText" parent="@android:style/Widget.Button">
    <item name="android:textColor" >@color/black</item>
    <item name="android:textSize" >12dip</item>
    <item name="android:textStyle" >bold</item>
    <item name="android:height" >44dip</item>
    <item name="android:background" >@drawable/button_selector</item>
    <item name="android:focusable" >true</item>
    <item name="android:clickable" >true</item>
    </style>

    <style name="ButtonNormalTextWithIcon" parent="ButtonNormalText">
    <item name="android:drawableLeft" >@drawable/ic_your_icon</item>
    </style>


    ButtonNormalTextWithIcon is a "child style" because it is extending ButtonNormalText (the "parent style").

    Note that changing the drawableLeft in the ButtonNormalTextWithIcon style, to drawableRight, drawableTop or drawableBottom you can place the icon in other position with respect to the text.

    IV. Go to the layout/ folder where you have your XML for the UI and go to the Button where you want to apply the style and make it look like this:

    <Button android:id="@+id/buttonSubmit"
    android:text="@string/button_submit"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    style="@style/ButtonNormalTextWithIcon" ></Button>


    And... voilĂ ! You got your button with an image at the left side.

    For me, this is the better way to do it! because doing it this way you can manage the text size of the button separately from the icon you want to display and use the same the background drawable for several buttons with different icons respecting the Android UI Guidelines using styles.

    You can also create a theme for your App and add the "parent style" to it so all the buttons look the same, and apply the "child style" with the icon only where you need it.

    Hope this helps! Cheers!

    P.D.: I will try to post this example with working code and images on my blogger and Github soon.

    ReplyDelete
  6. just replace

    android:background="@drawable/icon"


    with

    android:background="@android:color/transparent"
    android:drawableTop="@drawable/[your background image here]"


    this is a pretty good trick.. :D

    ReplyDelete
  7. Just use a LinearLayout and pretend it's a button - setting background and clickable is the key:

    <LinearLayout
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:drawable/btn_default"
    android:clickable="true"
    android:orientation="horizontal" >

    <ImageView
    android:id="@+id/img"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:layout_marginLeft="5dp"
    android:src="@drawable/image" />

    <TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:layout_margin="5dp"
    android:text="Do stuff" />
    </LinearLayout>

    ReplyDelete