4

I customized the Toggle button by using a drawable defined by using a selector. I use this drawable as background for the Toggle button.

<ToggleButton
    android:id="@+id/mailbox:toggle_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:layout_weight="1"
    android:background="@drawable/toggle_background"
    android:gravity="center_horizontal|center_vertical" />

The toggle_background is defined here:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:drawable="@drawable/img1"
            android:state_checked="true" />
        <item
            android:drawable="@drawable/img2"
            android:state_checked="false" />    
    </selector>

The problem is that the image is always stretched. Is there a way to define an image for the two states that is not stretched?

What I need is a background that will be stretched and in the center of the button an icon that must not be stretched.

Is it possible?

kingston
  • 11,053
  • 14
  • 62
  • 116

4 Answers4

13

This is my final solution.

In the layout:

<ToggleButton
    android:id="@+id/mailbox:toggle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"     
    android:background="@drawable/toggle_drawable_layers"/>

in the toggle_drawable_layers.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/toggle_drawable_bkg"></item>
    <item android:left="10dp" android:drawable="@drawable/toggle_drawable_left"
          android:gravity="center_vertical|center_horizontal" />
</layer-list>

in the toggle_drawable_left.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true">
        <bitmap android:src="@drawable/bitmap_checked"
          android:gravity="center_vertical|center_horizontal" />
    </item>
    <item android:state_checked="false">
        <bitmap android:src="@drawable/bitmap_unchecked"
          android:gravity="center_vertical|center_horizontal" />
    </item>        
</selector>
kingston
  • 11,053
  • 14
  • 62
  • 116
  • 2
    what is the toggle_drawable_bkg? when it comes? – Chandra Kiran Mar 21 '13 at 12:33
  • Your solution works. But I found that if you use `android:background="@null"` and `android:button="@drawable/toggle_drawable_left"` you can skip the use of the third xml file `toggle_drawable_layers.xml`. The images will not be stretched. – AlexAndro Aug 20 '14 at 13:21
5

I did the same task this way, the button:

        <ToggleButton  android:id="@+id/mlAbout"
            android:textOn="@string/about"
            android:textOff="@string/about"
            android:background="@drawable/ml_about" />

@drawable/ml_about:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/list_bg_top"></item>
    <item android:left="10dp">
        <bitmap android:src="@drawable/waiting_status_btn"
          android:gravity="center_vertical|left" />
    </item>
</layer-list>

@drawable/list_bg_top background image that will be stretched and @drawable/waiting_status_btn is the icon the will not be stretched with the widget

Dimanoid
  • 6,999
  • 4
  • 40
  • 55
  • 1
    The solution is implicitly given in the answer. The way to get a non stretched image is using a bitmap and not a drawable. I had to modify the proposed solution to allow having two different image for the different state: I used a drawable in the layer-list and then I defined the drawable by using a selector that for each state uses a bitmap – kingston Oct 05 '12 at 09:06
  • This is incorrect - if you want ToggleButton to behave with standard states. Supposing your waiting_status_btn is an XML drawable: You can't have an XML drawable as a src for a bitmap. As stated here: http://stackoverflow.com/questions/9788726/using-drawable-resources – albertpeiro Mar 31 '14 at 11:58
2

Just use bitmaps instead of drawables in your selector like so (no need to use layers):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/img1"
        android:state_checked="true" />
    <item
        android:drawable="@drawable/img2"
        android:state_checked="false" />    
</selector>

Also, don't forget to declare android:textOff="" android:textOn="" in your ToggleButton declaration

lytridic
  • 325
  • 4
  • 8
0

There is another way to overcome the issue of stretching:

Just convert the image into a Nine-Patch image, where the stretchable areas are just on all sides of the image.

Then Android will stretch the image only in invisible areas, and keep the visible image unchanged.

Jörg Eisfeld
  • 1,299
  • 13
  • 7