10

i'm setting background images to my custom buttons. I made a screenshot for my app and mentioned that when i'm using "wrap_content" for the width and height of the button, the button is stretched. When i'm fixing a size in dp, it will appear nice ( ex: in my mdpi folder i have 48x48px icons, so i put 48dp in width and height). Can you please explain me why?

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/definition_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="5dp"
android:layout_alignParentTop="true" >

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/buttons"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dp" >

    <Button
        android:id="@+id/addToFavorites"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:background="@drawable/favorites_button" />

    <Button
        android:id="@+id/fontup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:background="@drawable/fontup_button" />

    <Button
        android:id="@+id/fontdown"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:background="@drawable/fontdown_button" />

    <Button
        android:id="@+id/comment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:background="@drawable/comment_button" />

    <Button
        android:id="@+id/speak"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:background="@drawable/speak_button" />
    </LinearLayout>

    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:layout_below="@id/buttons">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/image_frame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <WebView
        android:id="@+id/webView1"
        android:layout_below="@id/image_frame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    </LinearLayout>
    </ScrollView>

    </RelativeLayout>

The code above shows my XML file. You can check this link to view a screenshot for my problem: https://www.dropbox.com/s/phnxt5p335ltqef/buttons_icon_altered.png

SubbaReddy PolamReddy
  • 2,083
  • 2
  • 17
  • 23
Anthony
  • 189
  • 1
  • 3
  • 16

3 Answers3

21

You can avoid the button background stretch by setting minWidth & minHeight to 0dp

<Button
    android:id="@+id/addToFavorites"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:minWidth="0dp"
    android:minHeight="0dp"
    android:layout_margin="5dp"
    android:background="@drawable/favorites_button" />
MCH
  • 239
  • 2
  • 3
8

It is pretty easy:

  • Use ImageButton instead of Button
  • set the background attribute to null
  • set the src attribute
  • set the scaleType attribute to centerInside

Working example:

<ImageButton
android:id="@+id/my_awesome_button"
android:scaleType="centerInside"
android:background="@null"
android:gravity="center"
android:layout_height="wrap_content" 
android:layout_width="wrap_content"
android:src="@drawable/my_awesome_drawable"/>

Note: You can also use a dp value instead of "wrap_content".

I hope it helps.

funcoder
  • 1,975
  • 20
  • 14
5

It appears stretched because "wrap_content" means android will stretch the image to fit the enclosing layout.

In your case, the buttons in the linear layout will take as much space as they can within the layout. So unless you set the height and width for the buttons, they will stretch out to fill the space occupied by the linear layout and consequently, their background images will also stretch along with the buttons.

But if you set the button size to 48dp, then the images won't have to stretch since they are also 48px in size and hence they will look nice.

Go through the excellent official developer docs for more info on layouts here: https://developer.android.com/guide/topics/ui/declaring-layout.html

and for learning how to manage your layouts and assets for multiple android screen sizes and resolutions here:

https://developer.android.com/guide/practices/screens_support.html

Anup Cowkur
  • 20,443
  • 6
  • 51
  • 84
  • They look nice on my Samsung galaxy tab 10.1 tablet (having mdpi screen), but when i'll open the same application on another mobile phone having an mdpi screen, they will occupy a big size or they will take a good space because "dp" is a dynamic unit? – Anthony Oct 09 '12 at 07:21
  • yes. An also because screen size comes into picture. YOur tab will have an extra large size screen. In that case, the image is being stretched proportionately in each direction, hence it's looking nice. – Anup Cowkur Oct 09 '12 at 07:25
  • So the tablet and the mobile phone (having the same dpi) but different screen sizes will use the same 48x48px icons? – Anthony Oct 09 '12 at 07:34
  • I checked the official android page about declaring layouts and this is the definition of "wrap_content" : wrap_content tells your view to size itself to the dimensions required by its content. So if a button has a bg image (48x48px) and i'm declaring my buttons with "wrap_content" so they must take 48x48px, and then the linear layout containing my buttons will occupy space required for these 4 buttons. So still didn't configure why icons are stretching in my case? – Anthony Oct 09 '12 at 08:08
  • 3
    The mistake you are making is that the background images are not considered as "content". If your button had any text on them, then those would be considered as "content". So right now, your buttons are just stretching to fill the linear layout. the background image will stretch to occupy whatever space is occupied by the button. Try putting some text to the buttons and you'll see how it works. The images will stretch to accomodate the text since the text is the "content", not the background image. Hope this helps – Anup Cowkur Oct 09 '12 at 08:51
  • this doesn't answer the question. What if I want to have a large button with small image in the center? – Radu Simionescu Oct 06 '14 at 13:12
  • This is incorrect. "It appears stretched because "wrap_content" means android will stretch the image to fit the enclosing layout." wrap content does not mean that it will stretch the background to fit the view, it means the view will match the size of the content. @AnupCowkur is correct. The problem is that the content of a button is text not the background. The answer below by MCH solves this issue. Just set the minWidth and minHeight to 0dp and then the button will only be the size of the background. – Randy Nov 08 '14 at 03:30