トグルボタンの実装

# トグルボタンとは
トグルボタンとは、ユーザが2つの状態(On/Off)を交互に切り替えることのできるUIです。
Androidでは`ToggleButton`や`CheckBox`がこれに当たります。
![ToggleButton](https://qiita-image-store.s3.amazonaws.com/0/48019/0712ec9f-a3f4-ffa0-de36-e7cc0dd677bc.png)


API Level 14でON/OFFをわかりやすく切り替えるための`View`として`Switch`が追加されました。
![Switch](https://qiita-image-store.s3.amazonaws.com/0/48019/ce0b8d46-958e-a75c-ee3a-8d1c5fe6d885.png)

http://developer.android.com/reference/android/widget/Switch.html

トグルボタンについてより詳しい解説は以下にあります。
http://developer.android.com/guide/topics/ui/controls/togglebutton.html

# 問題
残念ながら、`Switch`はSupportLibraryに含まれていません。
そのため、API Level 14未満の端末では`Switch`を使うことができません。

# 解決方法
主な解決方法は2つあります。

ひとつはAPI Level 14未満でも動作する`Switch`と似た`View`を自作することです。
GitHubでも以下のようなバックポートプロジェクトがいくつか存在します。
BoD/android-switch-backport
https://github.com/BoD/android-switch-backport

もうひとつの方法は、API Levelに応じて表示する`View`を差し替える方法です。
API Level 14以降では`Switch`、それ以前の端末であれば`ToggleButton`というように出し分けを行います。
一件複雑に思えますが、Androidではトグルボタン系のViewをまとめて`CompoundButton`として扱うことができるため、レイアウトファイルを分けるだけで簡単に対応することができます。

# 実装
まず、API Level 14未満の端末向けに`ToggleButton`を使ったレイアウトを定義します。
レイアウト階層に「API Level 14未満」という記述はできないので、デフォルトレイアウトに定義する形になります。

```/res/layout/activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MyActivity">

    <ToggleButton
        android:id="@+id/toggle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>
```

次に、API Level 14以上の端末向けに`Switch`を使ったレイアウトを定義します。
このとき、レイアウトファイル名とトグルボタンの`android:id`はは完全に一致させる必要があります。

```/res/layout-v14/activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MyActivity">

    <Switch
        android:id="@+id/toggle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>
```

最後に、`Activity`側の処理です。
ソースコード上では`Switch`も`ToggleButton`も一括して`CompoundButton`として扱います。
`CompoundButton`は`Switch`のように2つの状態を持つ`View`の抽象クラスで、状態の取得やリスナ関連の処理などが集約されており、
`Switch`、`ToggleButton`、`CheckBox`などはいずれも`CompoundButton`を継承したサブクラスになっています。

```Activity.java
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);

        CompoundButton toggle = (CompoundButton)findViewById(R.id.compoundButton);
        toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // 状態が変更された
                Toast.makeText(MyActivity.this, "isChecked : " + isChecked, Toast.LENGTH_SHORT).show();
            }
        });
    }
```

これでどちらのトグルボタンもタップ時に現在の状態に応じたトーストが表示されるようになります。

# 結果
ここまでの実装で、以下のように端末バージョンに応じて表示の出し分けができるようになりました。
1枚目が2.3端末、2枚目が4.4端末での表示となります。

<img src="https://qiita-image-store.s3.amazonaws.com/0/48019/4a7030f1-28ef-494e-f059-fde5349dadc7.png" width="360" />　<img src="https://qiita-image-store.s3.amazonaws.com/0/48019/3a49c919-b310-a0e2-c63a-983da610aa75.png" width="360" />