14

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

custom gender switch

What I feel like I need is something like a left/right drawable each in a green/white state, or alternatively a green outline with a drawable for when the choice should be selected.

What I don't understand in posts like this is how all the sample drawables provided slant to the right, and yet the 'on' button slants to the left.

I'm trying with the following 'thumb' drawable.

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

but it seems to cut the ends off the drawables. If I also set a track to something like this:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle" >

        <stroke 
            android:width="1dp" 
            android:color="@color/text_input"/>

        <corners
            android:radius="1dp"
            android:bottomLeftRadius="4.5dp"
            android:bottomRightRadius="4.5dp"
            android:topLeftRadius="4.5dp"
            android:topRightRadius="4.5dp" >
    </corners>
</shape>

then all I get is a thin line. So, I'm not sure what to try next.

Community
  • 1
  • 1
Mike T
  • 4,747
  • 4
  • 32
  • 52

5 Answers5

9

This cannot be with styling alone, this needs custom view implementation. Thats lot of code so my suggestion for you would be to use 3rd party libraries like https://github.com/hoang8f/android-segmented-control This library is tried and tested so its safe to use it instead of rewriting it.

Rajesh Batth
  • 1,672
  • 2
  • 19
  • 23
  • So, perhaps the answer is that this isn't a particularly Android-oriented design and that the design needs to change to fit more with Android's UI elements – Mike T Jun 20 '15 at 15:23
  • This design is derived from iOS, but the new SwitchCompat widget looks as good and simple as this widget, so give it a try . – Rajesh Batth Jun 20 '15 at 16:54
6

I have created an example app that you can find here that should solve your problem. You can have a look at this library that has a proper implementation of the segment control.

Basically I created a custom control that extends LinearLayout with a default weightSum of 2. Two Buttons are added with a weight of 1 and some logic is applied to toggle between them. On toggle an custom event is fired that is built on this interface.

public interface SwitchToggleListener {
    void onSwitchToggle(SwitchToggleState switchToggleState);
}

I used drawable resources to style the buttons.

The final result looked like this

enter image description here

the-ginger-geek
  • 7,041
  • 4
  • 27
  • 45
1

you can used RadioGroup with two RadioButton:

<RadioGroup
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:orientation="horizontal">

            <RadioButton
                    android:id="@+id/male_radio_button"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@drawable/selector_radio_btn_text"
                    android:background="@drawable/selector_radio_btn_left_bg"
                    android:gravity="center"
                    android:button="@null"
                    android:text="@string/male_radio_text"
                    />

            <RadioButton
                    android:id="@+id/female_radio_button"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@drawable/selector_radio_btn_text"
                    android:background="@drawable/selector_radio_btn_right_bg"
                    android:gravity="center"
                    android:button="@null"
                    android:text="@string/female_radio_text"/>
        </RadioGroup>

where selector_radio_btn_text.xml is text color selector:

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

and selector_radio_btn_left_bg(right bg).xml is backgorund of left and right side

Dmitry Ognev
  • 856
  • 1
  • 9
  • 9
1

Instead of his using any external libaray or support library this can be done easily by using RadioGroup and radio buttons. As "Dimitry " has mentioned in his answer I too have used the same thing to achieve. Here is the copy paste of my answer given for the question How to custom switch button?

  <RadioGroup
    android:checkedButton="@+id/offer"
    android:id="@+id/toggle"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:layout_marginBottom="@dimen/margin_medium"
    android:layout_marginLeft="50dp"
    android:layout_marginRight="50dp"
    android:layout_marginTop="@dimen/margin_medium"
    android:background="@drawable/pink_out_line"
    android:orientation="horizontal">

    <RadioButton
        android:layout_marginTop="1dp"
        android:layout_marginBottom="1dp"
        android:layout_marginLeft="1dp"
        android:id="@+id/search"
        android:background="@drawable/toggle_widget_background"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:button="@null"
        android:gravity="center"
        android:text="Search"
        android:textColor="@color/white" />

    <RadioButton
        android:layout_marginRight="1dp"
        android:layout_marginTop="1dp"
        android:layout_marginBottom="1dp"
        android:id="@+id/offer"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="@drawable/toggle_widget_background"
        android:button="@null"
        android:gravity="center"
        android:text="Offers"
        android:textColor="@color/white" />
</RadioGroup>

pink_out_line.xml

 <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="2dp" />
<solid android:color="#80000000" />
<stroke
    android:width="1dp"
    android:color="@color/pink" />
</shape>

toggle_widget_background.xml

      <?xml version="1.0" encoding="UTF-8"         standalone="no"?>
      <selector        xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:drawable="@color/pink" android:state_checked="true" />
     <item android:drawable="@color/dark_pink" android:state_pressed="true" />
     <item android:drawable="@color/transparent" />
    </selector>
Community
  • 1
  • 1
Sanjeet A
  • 5,171
  • 3
  • 23
  • 40
0

Update answer

to do this you should create layer-list in drawable folder

res/drawable/toggle_layerlist.xml

    <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/choice_right">
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <stroke 
        android:width="1dp" 
        android:color="@color/text_input"/>

    <corners
        android:radius="1dp"
        android:bottomLeftRadius="4.5dp"
        android:bottomRightRadius="4.5dp"
        android:topLeftRadius="4.5dp"
        android:topRightRadius="4.5dp" >
    </corners>
</shape>
    </item>

    </layer-list>

add layer list to your selector

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

    </selector>

use this selector as background , but make sure you empty text in on/off state

by set android:textOff="" android:textOn=""

<ToggleButton
            android:id="@+id/chkState"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/toggle_selector"
            android:textOff=""
            android:textOn=""/>

do the same to other state

Mina Fawzy
  • 20,852
  • 17
  • 133
  • 156