Switch-Button thumb gets skewed?

后端 未结 4 1209
说谎
说谎 2020-12-31 12:28

The thumb for my Switch-button seems to get skewed(for on&off state). There were similar problems on github, but those were for people making libraries to support Switch

相关标签:
4条回答
  • 2020-12-31 12:56

    I had the same requirement. I checked Android code and found that

    1. switch ignores any vertical margin/padding applied to a thumb shape drawable (thus thumb always touch the top and bottom of the track)
    2. the width of the thumb is calculated by taking the horizontal paddings + the max width of the on and off texts.

    This makes really hard to make a circle thumb.

    But if you specify the thumb drawable as a layer drawable for the sole reason to be able to specify padding for the single layer of the drawable, you can get the desired effect.

    Thumb selector:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item>
            <!--
            NOTE
            We want a thumb with padding around it inside the track.
            Sadly, a switch draws its track and thumb with the same height ignoring
            any padding of the drawable, so using a shape with padding does not work.
            To overcome, we apply a trick. We create layer list because the
            LayerListDrawable draws itself with taking the top, left, right, bottom
            values into account.
            -->
            <layer-list>
                <item
                    android:top="@dimen/switch_thumb_padding"
                    android:left="@dimen/switch_thumb_padding"
                    android:right="@dimen/switch_thumb_padding"
                    android:bottom="@dimen/switch_thumb_padding">
                    <!--
                    NOTE
                    No need to specify size because:
                      - The thumb fills the track in height.
                      - The thumb width is determined from thumb max(on, off) text +
                        text padding + drawable padding.
                    -->
                    <shape android:shape="oval">
                        <solid android:color="@color/switch_thumb"/>
                        <!-- NOTE did not work, had to set Switch's thumbTextPadding to the radius -->
                        <!--
                        <padding android:right="@dimen/switch_thumb_radius"
                                 android:left="@dimen/switch_thumb_radius"/>
                        -->
                    </shape>
                </item>
            </layer-list>
        </item>
    </selector>
    

    I set the on and off text of switch to empty (actually to "" to prevent warning about empty resource).

    track:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_enabled="false">
            <shape android:shape="rectangle">
                <size android:height="@dimen/switch_track_height"/>
                <corners android:radius="@dimen/switch_thumb_radius"/>
                <solid android:color="@color/switch_track_off"/>
            </shape>
        </item>
        <item android:state_checked="true">
            <shape android:shape="rectangle">
                <size android:height="@dimen/switch_track_height"/>
                <corners android:radius="@dimen/switch_thumb_radius"/>
                <solid android:color="@color/switch_track_on"/>
            </shape>
        </item>
    </selector>
    

    Switch style:

    <style name="CustomSwitch">
        <!-- NOTE this way the switch will be as width as required minimally -->
        <item name="android:switchMinWidth">0dp</item>
        <item name="android:track">@drawable/switch_track</item>
        <item name="android:thumb">@drawable/switch_thumb</item>
        <item name="android:textOff">@string/switch_thumb_off</item>
        <item name="android:textOn">@string/switch_thumb_on</item>
        <!-- NOTE if set to 0dp, the thumb was not visible even with padding
                  of the thumb drawable set to -->
        <item name="android:thumbTextPadding">@dimen/switch_thumb_radius</item>-->
        <!--<item name="android:thumbTextPadding">0dp</item>-->
    </style>
    

    And finally, the dimens:

    <dimen name="switch_track_height">30dp</dimen>
    <dimen name="switch_thumb_radius">15dp</dimen>
    <dimen name="switch_thumb_padding">2dp</dimen>
    

    So the only 'tricky' thing is to keep height = radius * 2.

    0 讨论(0)
  • 2020-12-31 12:59

    No clue why this happens but solved it by placing the Switch-button within a linearLayout. There must be some propery(width) of the thumb that has a "match_parent" of some sort that must've been causing it.

    Edit: It happens when I remove the default 'ON' and 'OFF' text. So to hide the text i changed its color to white. How to change textcolor of switch in Android

    main.java

    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.toggle_button);
    
        Switch sw = (Switch) findViewById(R.id.switch1);
    
                //Both of these need to be used to change the text color to white
                sw.setTextColor(Color.WHITE);
        sw.setSwitchTextAppearance(this, Color.WHITE);
    
                //Doing this would skew the circle
                //sw.setTextOn("  ");
        //sw.setTextOff("   ");
    }
    

    main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="70dp" >
    
        <Switch
            android:id="@+id/switch1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:thumb="@drawable/switch_thumb_selector"
            android:track="@drawable/switch_track_selector" />
    </LinearLayout>
    

    0 讨论(0)
  • 2020-12-31 13:02

    You can always horizontally stretch the graphic itself (ie, "switch_thumb.png") if you can't use the other answers.

    If you use the original software used to design the graphic and re-export it after stretching, it shouldn't cause blurring of the image. You'll have to eye-ball it for your dimensions, but starting at +30% stretching should get you close.

    0 讨论(0)
  • 2020-12-31 13:07

    For Custom Switch (Like IOS switch) I tried below Steps:

    Create a drawable track_selector.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_checked="true">
            <shape android:dither="true" android:shape="rectangle" android:useLevel="false" android:visible="true">
                <solid android:color="#ca120f" />
                <corners android:radius="25dp" />
                <size android:width="2dp" android:height="18dp" />
            </shape>
        </item>
        <item android:state_checked="false">
            <shape android:dither="true" android:shape="rectangle" android:useLevel="false" android:visible="true">
                <solid android:color="#27170432" />
                <corners android:radius="25dp" />
                <size android:width="2dp" android:height="18dp" />
            </shape>
        </item>
    </selector>
    

    Create a drawable thumb_selector.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_checked="false">
            <shape android:dither="true" android:shape="rectangle" android:useLevel="false" android:visible="true">
                <solid android:color="#ffffff" />
                <corners android:radius="100dp" />
                <size android:width="24dp" android:height="25dp" />
                <stroke android:width="4dp" android:color="#0000ffff" />
            </shape>
        </item>
    </selector>
    

    In your layout :

    <Switch
        android:id="@+id/checkboxAttendanceSelector"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_centerVertical="true"
        android:thumb="@drawable/thumb_selector"
        app:track="@drawable/track_selector" />
    

    Its working fine for me.

    0 讨论(0)
提交回复
热议问题