Освой программирование играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Switch

SwitchCompat

Switch - ещё один вид переключателей, который появился в Android 4.0 (API 14). Находится в разделах Commons и Buttons. Фактически, это замена немного устаревшего ToggleButton. В новых проектах лучше использовать Switch.

Компонент используется в том случае, когда нужно переключиться на противоположное состояние - да/нет, вкл./выкл., открыть/закрыть. В реальной жизни это выглядит следующим образом.

Если нужна поддержка старых устройств (7+), то можно использовать SwitchCompat из библиотеки совместимости.

Компонент представляет собой полоску с двумя состояниями и сопровождающим текстом. Переключиться можно сдвиганием ползунка или касанием экрана в области компонента (не только на самом ползунке, но и на сопровождающем тексте).

По умолчанию виджет находится в выключенном состоянии. Чтобы установить его в включенном состоянии на этапе разработки, используйте атрибут android:checked="true".

Сопровождающий текст задаётся в атрибуте android:text. А текст на самом переключателе задаётся при помощи атрибутов android:textOn (методы getTextOn() и setTextOn()) и android:textOff (методы getTextOff() и setTextOff()). Обратите внимание, что сопровождающий текст может быть очень большим и положение самого переключателя относительно этого текста можно регулировать при помощи атрибута android:gravity (смотри пример ниже). Если сопровождающий текст вам не нужен, то не используйте атрибут android:text.

Момент переключения можно отслеживать при помощи прослушки событий setOnCheckedChangeListener.

Зададим разметку для нескольких переключателей:


<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

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

        <Switch
            android:id="@+id/monitored_switch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="32dip"
            android:text="Переключатель с собственным текстом"
            android:textOff="Кошка"
            android:textOn="Кот" />

        <Switch
            android:layout_width="300dip"
            android:layout_height="wrap_content"
            android:layout_marginBottom="32dip"
            android:gravity="top|left"
            android:singleLine="false"
            android:text="This is an example of a switch with a lot of text in it. It may end up wrapping to another line. The switch will be pinned at the top." />

        <Switch
            android:layout_width="300dip"
            android:layout_height="wrap_content"
            android:layout_marginBottom="32dip"
            android:gravity="center_vertical|left"
            android:singleLine="false"
            android:text="This is an example of a switch with a lot of text in it. It may end up wrapping to another line. The switch will be vertically centered." />

        <Switch
            android:layout_width="300dip"
            android:layout_height="wrap_content"
            android:layout_marginBottom="32dip"
            android:gravity="bottom|left"
            android:singleLine="false"
            android:text="This is an example of a switch with a lot of text in it. It may end up wrapping to another line. The switch will be pinned at the bottom." />

        <Switch
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="32dip"
            android:text="Switch with match_parent width" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Standalone switch below:" />

        <Switch
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

</ScrollView>

И простой код для отслеживания момента переключения у одного из переключателей:


public class MainActivity extends Activity implements CompoundButton.OnCheckedChangeListener {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Switch switch = (Switch) findViewById(R.id.monitored_switch);
		if (switch != null) {
			switch.setOnCheckedChangeListener(this);
		}
	}
	
	@Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
       Toast.makeText(this, "Отслеживание переключения: " + (isChecked ? "on" : "off"),
               Toast.LENGTH_SHORT).show();
    }
}

Switch

SwitchCompat


compile 'com.android.support:appcompat-v7:25.1.1'

Если вы разрабатываете приложение под Material Design, то используйте SwitchCompat, который специально переработали под новые требования. Сравните внешний вид двух компонентов, чтобы увидеть разницу.


...
xmlns:app="http://schemas.android.com/apk/res-auto"
...

<android.support.v7.widget.SwitchCompat
    android:id="@+id/switch_compat"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:layout_marginLeft="50dp"
    android:checked="false"
    android:text="SwitchCompat"
    android:textOff="OFF"
    android:textOn="ON"
    app:showText="true"/>

<Switch
    android:id="@+id/switch1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/switch_compat"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="55dp"
    android:checked="false"
    android:text="Switch"
    android:textOff="Кошка"
    android:textOn="Кот"/>

SwitchCompat Switch

Как видите, новый компонент из библиотеки использует цвета темы из Material Design (colorAccent).

Для показа текста на кнопке переключателя установите в true значение атрибута app:showText.

Не забывайте, что данный компонент можно использовать только в активностях типа AppCompatActivity.

Вы можете задать свой стиль для SwitchCompat, добавив строки в styles.xml


<style name="MySwitch" parent="Theme.AppCompat.Light">
    <!-- активное состояние (30% прозрачности для фона) -->
    <item name="colorControlActivated">@android:color/holo_green_light</item>

    <!-- неактивное состояние ползунка -->
    <item name="colorSwitchThumbNormal">@android:color/holo_orange_dark</item>

    <!-- цвет дорожки для неактивного состояния (30% прозрачности) -->
    <item name="android:colorForeground">@android:color/darker_gray</item>
</style>

Применим стиль.


<android.support.v7.widget.SwitchCompat
    ...
    android:theme="@style/MySwitch" />

Для демонстрации эффекта вывел четыре переключателя. Первые два с заданным стилем в двух состояних. Третий и четвёртый - по умолчанию.

Style Switch

Цвет дорожки, вдоль которой двигается ползунок, можно поменять также через стиль:


<item name="trackTint">@android:color/holo_purple</item>

Поместим картинку в ползунок. Создадим в папке drawable файл switch_thumb.xml:


<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="oval">
            <solid android:color="@android:color/holo_orange_dark" />
        </shape>
    </item>
    <item android:bottom="2dp" android:left="1dp"
          android:right="1dp" android:top="1dp">
        <shape android:shape="oval">
            <solid android:color="@android:color/holo_blue_light" />
        </shape>
    </item>
    <item>
        <bitmap android:src="@android:drawable/ic_btn_speak_now"
                android:tint="@android:color/holo_red_light" />
    </item>
</layer-list>

Добавим новый атрибут компоненту.


<android.support.v7.widget.SwitchCompat
    android:id="@+id/switch_compat"

    android:thumb="@drawable/switch_thumb"
    android:theme="@style/MySwitch" />

SwitchCompat

Дополнительные материалы

GwonHyeok/StickySwitch: beautiful switch widget with sticky animation️

RiccardoMoro/RMSwitch: A simple and customizable two or three states Switch View

zagum/Android-SwitchIcon: Google launcher-style implementation of switch (enable/disable) icon

Реклама