2012年6月21日木曜日

[Android TIPS] iPhone みたいな ToggleButton

iPhone みたくスイッチ時にアニメーションする ToggleButton を自作してみました。
トグルボタンをタップすると8段階にアニメーションして状態が切り替わります。


サンプルの野良 apk はこちらからどうぞ。


パッケージ・エクスプローラーはこんなかんじ。


追加したのは下記のファイル
  • CustomToggleButton.java
  • toggle_off.xml
  • toggle_on.xml
  • toggle01~09.png

toggle01~09.png のボタンはこんなかんじ。


では、コードを順番に。まずは CustomToggleButton.java から。
package com.sample.togglesample;

import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;

/**
 * カスタムトグルボタンクラス
 */
public class CustomToggleButton extends ImageView {

 /** 値変更イベントリスナ */
 private OnToggleChangeListener mListener;

 /** チェック状態 */
 private boolean mChecked;

 /** チェック状態: setter */
 public boolean isChecked() {
  return mChecked;
 }

 /** チェック状態: getter */
 public void setChecked(boolean checked) {
  mChecked = checked;

  // チェック状態に応じて画像を変更
  if (mChecked) {
   this.setBackgroundResource(R.drawable.toggle09);
  } else {
   this.setBackgroundResource(R.drawable.toggle01);
  }

  // イベント発火
  if (mListener != null) {
   mListener.onChange(this, mChecked);
  }
 }

 /**
  * コンストラクタ
  * 
  * @param context
  * @param attrs
  */
 public CustomToggleButton(Context context, AttributeSet attrs) {
  super(context, attrs);
  
  // ウィジェットの初期化
  initWidget();
 }

 /**
  * ウィジェットの初期化
  */
 private void initWidget() {
  // 初期値は false に設定
  setChecked(false);

  // クリックされた際に自身の値を変更する
  setOnClickListener(new OnClickListener() {
   public void onClick(View v) {
    // 値を反転
    CustomToggleButton.this.setChecked(!CustomToggleButton.this.isChecked());

    // 実施するアニメーションを選択
    CustomToggleButton.this.setBackgroundResource(
      (CustomToggleButton.this.isChecked() ?
        R.drawable.toggle_on : R.drawable.toggle_off));

    // アニメーション開始
    AnimationDrawable frameAnimation = (AnimationDrawable)
      CustomToggleButton.this.getBackground();
    frameAnimation.start();
   }
  });
 }

 /**
  * イベントリスナの設定
  * 
  * @param listener
  */
 public void setOnToggleChangeListener(OnToggleChangeListener listener) {
  mListener = listener;
 }

 /**
  * 値変更イベントインタフェース
  */
 public interface OnToggleChangeListener {
  public void onChange(View v, boolean isChecked);
 }
}


次は toggle_off.xml。


    
    
    
    
    
    
    
    
    




次は toggle_on.xml。off の順番を逆にしただけ。


    
    
    
    
    
    
    
    
    




最後に main.xml と



    
    

    
    




MainActivity.java
package com.sample.togglesample;

import com.sample.togglesample.CustomToggleButton.OnToggleChangeListener;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

/**
 * サンプル画面クラス
 */
public class MainActivity extends Activity {

 /** トグルボタンの状態表示テキストビュー */
 private TextView mTxtValue;

 /** カスタムトグルボタンウィジェット */
 private CustomToggleButton mToggleButton;

 /**
  * onCreate
  */
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  // トグルボタンが押された際に値をテキストビューに表示
  mToggleButton = (CustomToggleButton) findViewById(R.id.customToggle);
  mToggleButton.setOnToggleChangeListener(new OnToggleChangeListener() {
   public void onChange(View v, boolean isChecked) {
    // トグルボタンの値を表示
    refreshToggleValue();
   }
  });

  // トグルボタンの値を表示
  mTxtValue = (TextView) findViewById(R.id.txtValue);
  refreshToggleValue();
 }

 /**
  * トグルボタンの値を表示
  */
 private void refreshToggleValue() {
  if (mTxtValue != null && mToggleButton != null) {
   mTxtValue.setText(mToggleButton.isChecked() ? "On" : "Off");
  }
 }
}

こんなかんじー。 スワイプして切り替えれるようにしたいけど、まずはタップからやってみました :-)