7

I'm trying to make a custom switch like this:

switch picture

with these properites:

  1. text on both sides always shown.
  2. different colors for on and off.

and these are two problems I faced since the switch only shows the text on the chosen side , and I can't seem to find a place where I can specify two different colors?

can I achieve this using the regular switch in android studio or must I use some library?

Thank you.

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
Outlandish
  • 243
  • 1
  • 2
  • 13
  • 1
    you can't specify the colors. Instead you will have to specify whole drawable for different states. As for text - you may want to place 2 textViews on top of switch to show On/Off text always instead of using Switch embedded text – Vladyslav Matviienko Sep 25 '18 at 11:18
  • You need this type of images.. then with selector drawable you can achieve this. you can find icons here https://icons8.com/ also you can customize them and add text in to them – Vidhi Dave Sep 25 '18 at 11:24
  • @VishvaDave thanks but my application supports two languages, hence I can't add the text on the icons, but I will try using selector drawable. – Outlandish Sep 25 '18 at 11:32
  • @VladyslavMatviienko thanks i'll try using drawables and see the result – Outlandish Sep 25 '18 at 11:34
  • 1
    i think this library can help you https://github.com/Angads25/android-toggle – Milad Bahmanabadi Sep 25 '18 at 11:46
  • was any of the supplied answers helpful to you? – Thomas Richter Sep 26 '18 at 07:16

3 Answers3

10

After researching I found a way that gives me exactly what I needed, this is what I got:

custom switch

in case of anyone looking for a way to do it, this is how:

based on this post answer , which worked great for me.

this is what I did, I created two drawables one for On and another for Off :

switch_on.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:state_checked="true" android:drawable="@color/colorGray"/>
    <item android:drawable="@color/colorPrimary" android:state_checked="true" />
    <item android:drawable="@color/colorPrimaryDark" android:state_pressed="true" />
    <item android:drawable="@color/transparent" />

</selector>

switch_off.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:state_checked="true" android:drawable="@color/colorGray"/>
    <item android:drawable="@color/gray_light" android:state_checked="true" />
    <item android:drawable="@color/black_overlay" android:state_pressed="true" />
    <item android:drawable="@color/transparent" />
</selector>

Next , created a drawable for the outline of the switch. outline.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="2dp" />
    <solid android:color="#80ffffff" />
    <stroke
        android:width="1dp"
        android:color="@color/gray_light" />
</shape>

one thing that I added is a drawable for the text color, because the color of the text changes depending on whether it's checked or not, this is it : switch_text.xml

<?xml version="1.0" encoding="utf-8"?>
<selector        xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@color/colorWhite"/>
    <item android:state_checked="true" android:color="@color/colorWhite"/>
    <item android:color="@color/gray_light"/>
</selector>

and finally, created RadioGroup in my layout this way:

<RadioGroup
        android:id="@+id/toggle"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:background="@drawable/outline"
        android:checkedButton="@+id/off"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/off"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginBottom="1dp"
            android:layout_marginStart="1dp"
            android:layout_marginTop="1dp"
            android:layout_weight="1"
            android:background="@drawable/switch_off"
            android:button="@null"
            android:gravity="center"
            android:padding="@dimen/fab_margin"
            android:text="@string/off"
            android:textColor="@drawable/switch_text" />

        <RadioButton
            android:id="@+id/on"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginBottom="1dp"
            android:layout_marginEnd="1dp"
            android:layout_marginTop="1dp"
            android:layout_weight="1"
            android:background="@drawable/switch_on"
            android:button="@null"
            android:gravity="center"
            android:padding="@dimen/fab_margin"
            android:text="@string/on"
            android:textColor="@drawable/switch_text" />
    </RadioGroup>

Notice the usage of each drawable in the right place:

android:background="@drawable/outline" for the RadioGroup android:background="@drawable/switch_off" for the first RadioButton android:background="@drawable/switch_on" for the second RadioButton android:textColor="@drawable/switch_text" for both Radio Buttons

And that's all.

Outlandish
  • 243
  • 1
  • 2
  • 13
  • I used this solution finally after exhausting finding other libraries and trying to make it work. Damn cannot imagine why android don't have this basic component. Apple has it as Segmented Control. – GeneCode Dec 12 '21 at 16:30
0

To create ON and OFF labels for the switch you can use the attributes android:textOn and android:textOff with the switch declaration. To ensure, that the text lebals are always displayed, especially for API Level bigger API21, also use this attribute: android:showText="true". Then your switch should look like this:

<Switch
    android:id="@+id/switcher"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textOff="OFF"
    android:textOn="ON"
    android:showText="true"
/>


In order to change the default color, you have to specify a seperate design for it like that:

1. In file values\styles.xml define a style like that:

<style name="CustomSwitchTheme" parent="Theme.AppCompat.Light">
    <item name="android:colorControlActivated">#FF0000</item>
</style>

It is important, that you also reference the correct parent theme.


2. After defining the new switch style, you can link your custom style to the switch with the attribute

android:theme="@style/CustomSwitchTheme"

Finally your Switch should look like that:

<Switch
    android:id="@+id/switcher"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textOff="OFF"
    android:textOn="ON"
    android:showText="true"
    android:theme="@style/CustomSwitchTheme"
/>
Thomas Richter
  • 833
  • 8
  • 20
  • 2
    Thanks Thomas, I tried your solution but the issue with this method that it only shows the text of the checked option , what I wanted was for both texts to be shown. anyways, I found a solution using RadioGroup and I'll post it soon. Thank you for your help. – Outlandish Sep 26 '18 at 09:25
0

Use ToggleButton(change height/width as per image ratio) & selector, here's the code

<ToggleButton
      android:id="@+id/toggle_"
      android:layout_width="60dp"
      android:layout_height="30dp"
      android:layout_alignParentStart="true"
      android:background="@drawable/on_off"
      android:textOff=""
      android:textOn=""/>

<selector
   xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_checked="true"
   android:drawable="@drawable/ic_on"  />
   <item android:state_checked="false"
   android:drawable="@drawable/ic_off"  />
</selector>