Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly scale custom thumb for a switch widget?

I've a custom thumb set from a drawable for a Switch widget inside a LinearLayout. I can't get it to show correctly on all kinds of screens. On most screens, it looks like this-

correct

Which is fine, but on some screens (example - 440 dpi), it'd look like this-

wrong

How do I get this to look uniform across all screens? I've tried many things, including switchMinWidth, setting android:width= to 0dp, using thumbTextPadding but nothing works. Everything has the exact same result, it works on some screens but not on others.

Here's my Switch widget placed inside a LinearLayout with a layout_weight of 2. There are usually 5 widgets in each Horizontal LinearLayout but this specific one has 4 as Switch is supposed to take 2 slots.

        <Switch
            android:id="@+id/btndegreerad"
            style="?android:attr/borderlessButtonStyle"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:background="@drawable/degree_rad_track"
            android:showText="true"
            android:switchTextAppearance="@style/SwitchTextTheme"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:textOff="@string/btnrad"
            android:textOn="@string/btndegree"
            android:thumb="@drawable/degree_rad_thumb"
            android:thumbTextPadding="@dimen/_3sdp"
            android:thumbTint="@color/colorSwitch"
            android:track="@drawable/degree_rad_track" />

Here's the degree_rad_thumb drawable-

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="false">
        <shape android:shape="rectangle">
            <size android:height="@dimen/_38sdp" android:width="0dp"/>
            <corners android:bottomRightRadius="10dp"
                android:bottomLeftRadius="10dp"
                android:topRightRadius="10dp"
                android:topLeftRadius="10dp"/>
        </shape>
    </item>
    <item android:state_checked="true">
        <shape android:shape="rectangle">
            <size android:height="@dimen/_38sdp" android:width="0dp"/>
            <corners android:bottomRightRadius="10dp"
                android:bottomLeftRadius="10dp"
                android:topRightRadius="10dp"
                android:topLeftRadius="10dp"/>
        </shape>
    </item>
</selector>

Here's also degree_rad_track, though this is probably not needed-

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="false">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorFadedPrimary"/>
            <corners android:bottomRightRadius="10dp"
                android:bottomLeftRadius="10dp"
                android:topRightRadius="10dp"
                android:topLeftRadius="10dp"/>
        </shape>
    </item>
    <item android:state_checked="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorFadedPrimary"/>
            <corners android:bottomRightRadius="10dp"
                android:bottomLeftRadius="10dp"
                android:topRightRadius="10dp"
                android:topLeftRadius="10dp"/>
        </shape>
    </item>
</selector>
like image 860
Chase Avatar asked Oct 15 '22 06:10

Chase


2 Answers

If you want to correctly scale to all screens on anything; My best rules are using ScrollView and RelativeLayout/ConstraintLayout in general so it's usable and scales.

You can choose between ConstraintLayout and RelativeLayout; Both should scale correctly, perhaps Relative is easier since you don't have to set the constraints. ScrollView isn't necessarily needed here since we don't have a lot of data.

Try putting your Switch inside a RelativeLayout/ConstraintLayout and it should work.

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <Switch
                    android:id="@+id/btndegreerad"
                    style="?android:attr/borderlessButtonStyle"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="2"
                    android:background="@drawable/degree_rad_track"
                    android:showText="true"
                    android:switchTextAppearance="@style/SwitchTextTheme"
                    android:textAppearance="@style/TextAppearance.AppCompat.Body1"
                    android:textOff="@string/btnrad"
                    android:textOn="@string/btndegree"
                    android:thumb="@drawable/degree_rad_thumb"
                    android:thumbTextPadding="@dimen/_3sdp"
                    android:thumbTint="@color/colorSwitch"
                    android:track="@drawable/degree_rad_track" />

            </RelativeLayout>

        </LinearLayout>

Note: Customise the layouts as you want

Hope it helps.

like image 113
unobatbayar Avatar answered Nov 01 '22 09:11

unobatbayar


I am currently working on a similar layout using Switch with custom drawable for its thumb and track. From what I have learned, LinearLayout weight property can affect your Switch track's drawable (either cropped or squished) if your device width doesn't provide enough room.

With this unwanted behavior, I recommend changing your layout type to ConstraintLayout if you really need to get your custom drawable working on different screen sizes. This solution is also recommended in this guide.

But if you really want to use LinearLayout, don't use layout_weight for your Switch.

like image 26
Harry Timothy Avatar answered Nov 01 '22 07:11

Harry Timothy