73

In Ice Cream Sandwich a Switch Widget was introduced that displays an On Off Slider.

I added the Switch like this:

<Switch 
    android:layout_width="fill_parent"
    android:layout_height="48dp"
    android:textStyle="bold"
    android:thumb="@drawable/switch_thumb_selector"
    android:track="@drawable/switch_bg_selector" />

The track and thumb drawables are nine patch images that should scale to all possible sizes. I hoped that the Switch would scale to the maximum size inside the given bounds, but it seems as if the drawables are just centered inside the supplied space.

Is it possible to increase the size of the Switch to make it appear bigger?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Janusz
  • 187,060
  • 113
  • 301
  • 369

7 Answers7

118

Using scale property to change size worked for me.

Add these lines to your <switch/> tag in xml file.

android:scaleX="2"
android:scaleY="2"

You can change scale value as per your need. Here value 2 makes it double in size, similarly value 0.5 makes it half in size.

Example:

       <Switch
            android:id="@+id/switchOnOff"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scaleX="2"
            android:scaleY="2"/>
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Gaurav
  • 1,965
  • 2
  • 16
  • 32
  • 13
    be careful, the parent layout won't wrap_content correctly and the switch widget could be cut off by the parent's bounds – marcos E. May 02 '18 at 11:53
  • 3
    This answer is promising but not complete. As @marcos E. says, the layout of the switch is not updated properly. If text is used it also gets scaled and gets cut off. – AlanKley Jun 15 '18 at 17:35
  • 3
    this also makes the switch blurry – oziomajnr May 26 '19 at 17:17
110

I think I finally figured this out:

  1. Switch caption size is controlled by <switch android:textSize=""... />
  2. Switch thumb text size is controlled by <switch android:switchTextAppearance="".../>. Cook up a style of your own. This style is important because it controls the overall width of the thumb (more on this later).
  3. Overall switch height is controlled by <switch android:track="@drawable/shape_mythumb".../>. You used a nine patch, which I suspect is why you are having a problem. I used a <shape android:shape="rectangle"...></shape> and was successful.
  4. The height of the thumb drawable <switch android:thumb="".../> is adjusted to match the height of the track. The height of the thumb's drawable is only important to the shape of the thumb. It does not effect the height of the switch.

So here's what I found:

  1. Use <shape>...</shape> drawables for both the switch thumb and switch track.
  2. The width of both drawables is irrelavant. I set mine to "0dp"
  3. The track's height determines the switch's overall height.
  4. The longest string of android:textOff or android:textOn will determine the width of the thumb. This determines the width of the entire switch. Switch width is always twice the width of the thumb.
  5. If the thumb text width is less that the height of the track, the thumb shape will be scaled down. This can distort the shape of the thumb. If this happens, add spaces to increase the width of your "off" or "on" text until it is at least as wide as your track is tall.

This is enough information to at least start designing switches to the size and shape that you want them. Let me know if you figure out anything else.

Quantium
  • 1,779
  • 1
  • 14
  • 14
  • 2
    deserves an upvote.. the track is the one that determines the size of the switch. And the shape trick works. I had to go through the hard way of creating nine patches with different heights for different devices.and finally got this solution.Thanks. – Rat-a-tat-a-tat Ratatouille Jan 09 '14 at 17:59
  • @quantium Do you have a special example to this? Because I have the same problem but your solution doesnt work for me. I think I'm doing something wrong. –  Mar 06 '14 at 08:19
  • 1
    When I use this code and apply the xmls to my thumb and track attributes, the switch disappears. Can somebody help with this? – Brandon Feb 06 '16 at 01:39
  • @David it's not all about code, explaining the solution is just as well, sometimes code is not enough. – Eman Mar 27 '19 at 15:33
  • Now how to use custom images for the thumb and the track like if I am creating a realistic power ON OFF switch. – Maseed May 25 '19 at 10:57
52

The above Answer is right. here is a small example how to change your switch width using shape drawable I hope it will help some one..

1) Use ur color for thumb (color_thumb.xml)

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <size android:height="40dp"  />
    <gradient android:height="40dp" android:startColor="#FF569BDA" android:endColor="#FF569BDA"/>
</shape>

2) gray color for track (gray_track.xml)

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <size android:height="40dp"  />
    <gradient android:height="40dp" android:startColor="#dadadada" android:endColor="#dadadada"/>
</shape>

3) Selector for thumb (thumb.xml)

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:drawable="@drawable/gray_track" />
    <item android:state_pressed="true"  android:drawable="@drawable/color_thumb" />
    <item android:state_checked="true"  android:drawable="@drawable/color_thumb" />
    <item                               android:drawable="@drawable/gray_track" />
</selector>

4) Selector for track (track.xml)

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true"  android:drawable="@drawable/color_thumb" />
     <item                               android:drawable="@drawable/gray_track" />
</selector>

and finally in switch

use

android:switchMinWidth="56dp"
android:thumb="@drawable/thumb"
android:track="@drawable/track"
Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79
Asthme
  • 5,163
  • 6
  • 47
  • 65
11

I dealt with a similar issue today and I found out that starting from Jelly Bean you can use setSwitchMinWidth(width); to set the minimum width of the complete switch. I also figured however that if your texts are too big, the widget is just cut off on the left part. Changing the default text padding on the thumb might come in handy here, with setThumbTextPadding(num); you can modify that.

The only problem - and this is a blocker actually - I've stumbled so far is that one should of course expand the switch according to the size of the parent container. For that I wrapped the switch in a custom linear layout (which also provides a fallback for API <= 15) and tried this:

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    if (android.os.Build.VERSION.SDK_INT >= 16) {
        adaptSwitchWidth(w);
    }
}

@TargetApi(16)
private void adaptSwitchWidth(int containerWidth) {
    Switch sw = (Switch) compoundButton;
    sw.setSwitchMinWidth(containerWidth);
}

Unfortunately - for whatever stupid reason - the switch widget doesn't react on that. I tried to do that in an OnLayoutChangeListener without having success either. Ideally, the current size of the switch should also be known at that state and I wanted to "distribute" the free space to the padding like this:

int textPadding = Math.max(0, (sw.getWidth() - containerWidth) / 4);
sw.setThumbTextPadding(textPadding);

but sw.getWidth() still returns 0 in onSizeChanged(), probably because it is still not layed out properly. Yeah, we're almost there... if you stumble across something, let me know :)

Thomas Keller
  • 5,933
  • 6
  • 48
  • 80
9

The track's height doesn't have to visually determine the thumb/switch overall height. I added a transparent stroke to my track drawable shape which results in a padding around the track:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="@color/track_color"/>
    <size android:height="@dimen/track_height"  />
    <size android:width="@dimen/track_width"  />

    <!-- results in the track looking smaller than the thumb -->
    <stroke
        android:width="6dp"
        android:color="#00ffffff"/>
</shape>
stevenp
  • 441
  • 6
  • 5
3

There is also an option to provide a minimun width using app:switchMinWidth:

    <androidx.appcompat.widget.SwitchCompat
        android:id="@+id/nav_header_available_switch"
        style="@style/Widget.AppCompat.CompoundButton.Switch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:switchMinWidth="80dp"
        android:scaleY="1.3"
        tools:checked="true" />
Alberto
  • 426
  • 6
  • 16
1

Use SwitchCompat instead of Switch and scaleX, sxaleY, padding works better

<androidx.appcompat.widget.SwitchCompat
                android:id="@+id/switch_transport"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="15dp"
                android:scaleX="1.5"
                android:scaleY="1.5"/>
윤민혁
  • 11
  • 1