Android SwitchButton(滑动开关)

@RemoteView
public class Button extends TextView {
  public Button(Context context) {
    this(context, null);
  }

  public Button(Context context, AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.buttonStyle);
  }

  public Button(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(event);
    event.setClassName(Button. class.getName());
  }

  @Override
  public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(info);
    info.setClassName(Button. class.getName());
  }
}

  是直接继承于TextView,所不同的是在构造方法中添加了Button的样式,并且在初始化可见性方面交由Button类自己来处理。虽然Button的实现比较简单,但是它的子类并不是这样。看一下:


  直接子类只有有一个,CompoundButton。它是一个抽象类,而实现这个类的控件正是 CheckBoxRadioButtonSwitchToggleButton 这四个,所以先重点说一下它。源码如下:

  
/**
 * <p>
 * A button with two states, checked and unchecked. When the button is pressed
 * or clicked, the state changes automatically.
 * </p>
 *
 * <p><strong>XML attributes </strong></p>
 * <p>
 * See {@link android.R.styleable#CompoundButton
 * CompoundButton Attributes}, {@link android.R.styleable#Button Button
 * Attributes}, {@link android.R.styleable#TextView TextView Attributes}, {@link
 * android.R.styleable #View View Attributes}
 * </p>
 */
public abstract class CompoundButton extends Button implements Checkable {
  private boolean mChecked ;
  private int mButtonResource ;
  private boolean mBroadcasting ;
  private Drawable mButtonDrawable;
  private OnCheckedChangeListener mOnCheckedChangeListener;
  private OnCheckedChangeListener mOnCheckedChangeWidgetListener ;

  private static final int[] CHECKED_STATE_SET = {
    R.attr.state_checked
  };

  public CompoundButton(Context context) {
    this(context, null);
  }

  public CompoundButton(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public CompoundButton(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    TypedArray a =
        context.obtainStyledAttributes(
            attrs, com.android.internal.R.styleable.CompoundButton, defStyle, 0);

    Drawable d = a.getDrawable(com.android.internal.R.styleable.CompoundButton_button);
    if (d != null ) {
      setButtonDrawable(d);
    }

    boolean checked = a
        .getBoolean(com.android.internal.R.styleable.CompoundButton_checked, false);
    setChecked(checked);

    a.recycle();
  }

  public void toggle() {
    setChecked(! mChecked);
  }

  @Override
  public boolean performClick() {
    /*
     * XXX: These are tiny, need some surrounding ‘expanded touch area‘,
     * which will need to be implemented in Button if we only override
     * performClick()
     */

    /* When clicked, toggle the state */
    toggle();
    return super .performClick();
  }

  @ViewDebug.ExportedProperty
  public boolean isChecked() {
    return mChecked ;
  }

  /**
   * <p>Changes the checked state of this button.</p>
   *
   * @param checked true to check the button, false to uncheck it
   */
  public void setChecked(boolean checked) {
    if (mChecked != checked) {
      mChecked = checked;
      refreshDrawableState();
      notifyViewAccessibilityStateChangedIfNeeded(
          AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED );

      // Avoid infinite recursions if setChecked() is called from a listener
      if (mBroadcasting ) {
        return;
      }

      mBroadcasting = true ;
      if (mOnCheckedChangeListener != null) {
        mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
      }
      if (mOnCheckedChangeWidgetListener != null) {
        mOnCheckedChangeWidgetListener .onCheckedChanged(this, mChecked);
      }

      mBroadcasting = false ;		   
    }
  }

  /**
   * Register a callback to be invoked when the checked state of this button
   * changes.
   *
   * @param listener the callback to call on checked state change
   */
  public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
    mOnCheckedChangeListener = listener;
  }

  /**
   * Register a callback to be invoked when the checked state of this button
   * changes. This callback is used for internal purpose only.
   *
   * @param listener the callback to call on checked state change
   * @hide
   */
  void setOnCheckedChangeWidgetListener(OnCheckedChangeListener listener) {
    mOnCheckedChangeWidgetListener = listener;
  }

  /**
   * Interface definition for a callback to be invoked when the checked state
   * of a compound button changed.
   */
  public static interface OnCheckedChangeListener {
    /**
     * Called when the checked state of a compound button has changed.
     *
     * @param buttonView The compound button view whose state has changed.
     * @param isChecked  The new checked state of buttonView.
     */
    void onCheckedChanged(CompoundButton buttonView, boolean isChecked);
  }

  /**
   * Set the background to a given Drawable, identified by its resource id.
   *
   * @param resid the resource id of the drawable to use as the background
   */
  public void setButtonDrawable(int resid) {
    if (resid != 0 && resid == mButtonResource ) {
      return;
    }

    mButtonResource = resid;

    Drawable d = null;
    if (mButtonResource != 0) {
      d = getResources().getDrawable(mButtonResource );
    }
    setButtonDrawable(d);
  }

  /**
   * Set the background to a given Drawable
   *
   * @param d The Drawable to use as the background
   */
  public void setButtonDrawable(Drawable d) {
    if (d != null ) {
      if (mButtonDrawable != null) {
        mButtonDrawable.setCallback(null);
        unscheduleDrawable( mButtonDrawable);
      }
      d.setCallback( this);
      d.setVisible(getVisibility() == VISIBLE, false);
      mButtonDrawable = d;
      setMinHeight(mButtonDrawable .getIntrinsicHeight());
    }

    refreshDrawableState();
  }

  @Override
  public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(event);
    event.setClassName(CompoundButton.class .getName());
    event.setChecked( mChecked);
  }

  @Override
  public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(info);
    info.setClassName(CompoundButton.class .getName());
    info.setCheckable( true);
    info.setChecked( mChecked);
  }

  @Override
  public int getCompoundPaddingLeft() {
    int padding = super.getCompoundPaddingLeft();
    if (!isLayoutRtl()) {
      final Drawable buttonDrawable = mButtonDrawable;
      if (buttonDrawable != null) {
        padding += buttonDrawable.getIntrinsicWidth();
      }
    }
    return padding;
  }

  @Override
  public int getCompoundPaddingRight() {
    int padding = super.getCompoundPaddingRight();
    if (isLayoutRtl()) {
      final Drawable buttonDrawable = mButtonDrawable;
      if (buttonDrawable != null) {
        padding += buttonDrawable.getIntrinsicWidth();
      }
    }
    return padding;
  }

  /**
   * @hide
   */
  @Override
  public int getHorizontalOffsetForDrawables() {
    final Drawable buttonDrawable = mButtonDrawable ;
    return (buttonDrawable != null) ? buttonDrawable.getIntrinsicWidth() : 0;
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    final Drawable buttonDrawable = mButtonDrawable ;
    if (buttonDrawable != null) {
      final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK ;
      final int drawableHeight = buttonDrawable.getIntrinsicHeight();
      final int drawableWidth = buttonDrawable.getIntrinsicWidth();

      int top = 0;
      switch (verticalGravity) {
        case Gravity.BOTTOM :
          top = getHeight() - drawableHeight;
          break;
        case Gravity.CENTER_VERTICAL :
          top = (getHeight() - drawableHeight) / 2;
          break;
      }
      int bottom = top + drawableHeight;
      int left = isLayoutRtl() ? getWidth() - drawableWidth : 0;
      int right = isLayoutRtl() ? getWidth() : drawableWidth;

      buttonDrawable.setBounds(left, top, right, bottom);
      buttonDrawable.draw(canvas);
    }
  }

  @Override
  protected int[] onCreateDrawableState(int extraSpace) {
    final int [] drawableState = super.onCreateDrawableState(extraSpace + 1);
    if (isChecked()) {
      mergeDrawableStates(drawableState, CHECKED_STATE_SET);
    }
    return drawableState;
  }

  @Override
  protected void drawableStateChanged() {
    super.drawableStateChanged();
     
    if (mButtonDrawable != null) {
      int[] myDrawableState = getDrawableState();
       
      // Set the state of the Drawable
      mButtonDrawable.setState(myDrawableState);
       
      invalidate();
    }
  }

  @Override
  protected boolean verifyDrawable(Drawable who) {
    return super .verifyDrawable(who) || who == mButtonDrawable;
  }

  @Override
  public void jumpDrawablesToCurrentState() {
    super.jumpDrawablesToCurrentState();
    if (mButtonDrawable != null) mButtonDrawable.jumpToCurrentState();
  }

  static class SavedState extends BaseSavedState {
    boolean checked ;

    /**
     * Constructor called from {@link CompoundButton#onSaveInstanceState()}
     */
    SavedState(Parcelable superState) {
      super(superState);
    }
     
    /**
     * Constructor called from {@link #CREATOR}
     */
    private SavedState(Parcel in) {
      super(in);
      checked = (Boolean)in.readValue( null);
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
      super.writeToParcel(out, flags);
      out.writeValue( checked);
    }

    @Override
    public String toString() {
      return "CompoundButton.SavedState{"
          + Integer.toHexString(System.identityHashCode(this))
          + " checked=" + checked + "}" ;
    }

    public static final Parcelable.Creator<SavedState> CREATOR
        = new Parcelable.Creator<SavedState>() {
      public SavedState createFromParcel(Parcel in) {
        return new SavedState(in);
      }

      public SavedState[] newArray(int size) {
        return new SavedState[size];
      }
    };
  }

  @Override
  public Parcelable onSaveInstanceState() {
    // Force our ancestor class to save its state
    setFreezesText( true);
    Parcelable superState = super.onSaveInstanceState();

    SavedState ss = new SavedState(superState);

    ss. checked = isChecked();
    return ss;
  }

  @Override
  public void onRestoreInstanceState(Parcelable state) {
    SavedState ss = (SavedState) state;
 
    super.onRestoreInstanceState(ss.getSuperState());
    setChecked(ss. checked);
    requestLayout();
  }
}
   先从构造方法开始,在构造方法中,
public CompoundButton(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);

  TypedArray a =
    context.obtainStyledAttributes(
      attrs, com.android.internal.R.styleable.CompoundButton, defStyle, 0);

  Drawable d = a.getDrawable(com.android.internal.R.styleable.CompoundButton_button);
  if (d != null ) {
      setButtonDrawable(d);
  }

  boolean checked = a
    .getBoolean(com.android.internal.R.styleable.CompoundButton_checked, false);
  setChecked(checked);

  a.recycle();
    }
   先是从attrs中读取定义的属性,一个是Drawable用于设置背景;一个是布尔类型变量用于判断是否check过。设置背景使用的是setButtonDrawable()方法,代码如下:
/**
   * Set the background to a given Drawable
   *
   * @param d The Drawable to use as the background
   */
  public void setButtonDrawable(Drawable d) {
    if (d != null ) {
      if (mButtonDrawable != null) {
        mButtonDrawable.setCallback(null);
        unscheduleDrawable( mButtonDrawable);
      }
      d.setCallback( this);
      d.setVisible(getVisibility() == VISIBLE, false);
      mButtonDrawable = d;
      setMinHeight(mButtonDrawable .getIntrinsicHeight());
    }

    refreshDrawableState();
  }
  这个方法写的就比较完善,可以作为一个学习的典范。首先判断传递过来的Drawable是否为空,如果不为空并且默认的Drawable也不为空,那么取消默认Drawable的callback,然后调用 unscheduleDrawable 方法。这个方法代码如下:
/**
  * Unschedule any events associated with the given Drawable.  This can be
  * used when selecting a new Drawable into a view, so that the previous
  * one is completely unscheduled.
  *
  * @param who The Drawable to unschedule.
  *
  * @see #drawableStateChanged
  */
    public void unscheduleDrawable(Drawable who) {
     if (mAttachInfo != null && who != null) {
      mAttachInfo.mViewRootImpl .mChoreographer.removeCallbacks(
        Choreographer.CALLBACK_ANIMATION, null, who);
     }
    }

   从方法注释中可以看出它的用途,正是更换Drawable时候使用的。接下来开始重新设置Drawable,包括回调、可见性、最小高度。最后调用 refreshDrawableState() 方法,这个是View类的方法,用于更新Drawable状态。

  然后再回过头看一下 setChecked (checked) 方法,这个用于设置check,也就是button的点击状态。代码如下:

/**
   * <p>Changes the checked state of this button.</p>
   *
   * @param checked true to check the button, false to uncheck it
   */
  public void setChecked( boolean checked) {
    if (mChecked != checked) {
      mChecked = checked;
      refreshDrawableState();
      notifyViewAccessibilityStateChangedIfNeeded(
          AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED );

      // Avoid infinite recursions if setChecked() is called from a listener
      if (mBroadcasting ) {
        return;
      }

      mBroadcasting = true ;
      if (mOnCheckedChangeListener != null) {
        mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
      }
      if (mOnCheckedChangeWidgetListener != null) {
        mOnCheckedChangeWidgetListener .onCheckedChanged(this, mChecked);
      }
      mBroadcasting = false ;		   
    }
  }

  在这个方法中多出了一个接口,这个接口真是check的一个回调接口,代码如下:

/**
     * Interface definition for a callback to be invoked when the checked state
     * of a compound button changed.
     */
    public static interface OnCheckedChangeListener {
        /**
         * Called when the checked state of a compound button has changed.
         *
         * @param buttonView The compound button view whose state has changed.
         * @param isChecked  The new checked state of buttonView.
         */
        void onCheckedChanged(CompoundButton buttonView, boolean isChecked);
    }

  这种回调接口在Android中处处可见,之前的文章也有介绍过。但是在上面的方法,它使用了一个mBroadcasting变量,进而巧妙地避免了重复递归的问题,大家自己感受一下。

  然后就是ondraw()方法了,把之前的drawable画出来。代码如下:

@Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    final Drawable buttonDrawable = mButtonDrawable ;
    if (buttonDrawable != null) {
      final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK ;
      final int drawableHeight = buttonDrawable.getIntrinsicHeight();
      final int drawableWidth = buttonDrawable.getIntrinsicWidth();

      int top = 0;
      switch (verticalGravity) {
        case Gravity.BOTTOM :
          top = getHeight() - drawableHeight;
          break;
        case Gravity.CENTER_VERTICAL :
          top = (getHeight() - drawableHeight) / 2;
          break;
      }
      int bottom = top + drawableHeight;
      int left = isLayoutRtl() ? getWidth() - drawableWidth : 0;
      int right = isLayoutRtl() ? getWidth() : drawableWidth;

      buttonDrawable.setBounds(left, top, right, bottom);
      buttonDrawable.draw(canvas);
    }
  }

  看得出来,在onDrawable()方法中,最主要的部分还是如何确定上下左右四个参数。确定完后就可以画出来了。但是,CompoundButton是一个抽象类,并不能直接使用,那看一下它的子类是如何实现的:

1、CheckBox
public class CheckBox extends CompoundButton {
  public CheckBox(Context context) {
    this(context, null);
  }
   
  public CheckBox(Context context, AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.checkboxStyle);
  }

  public CheckBox(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(event);
    event.setClassName(CheckBox. class.getName());
  }

  @Override
  public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(info);
    info.setClassName(CheckBox. class.getName());
  }
}

  和Button的实现差不多,使用了一个自己的样式。并且也是重写了那两个方法。再来看一下RadioButton,

public class RadioButton extends CompoundButton {
   
  public RadioButton(Context context) {
    this(context, null);
  }
   
  public RadioButton(Context context, AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.radioButtonStyle);
  }

  public RadioButton(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  /**
   * {@inheritDoc}
   * <p>
   * If the radio button is already checked, this method will not toggle the radio button.
   */
  @Override
  public void toggle() {
    // we override to prevent toggle when the radio is already
    // checked (as opposed to check boxes widgets)
    if (!isChecked()) {
      super.toggle();
    }
  }

  @Override
  public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(event);
    event.setClassName(RadioButton. class.getName());
  }

  @Override
  public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(info);
    info.setClassName(RadioButton. class.getName());
  }
}

   和CheckBox实现差不多,区别在于多重写了一个方法,用于防止按钮被重复点击。另外还有ToggleButton以及Switch,前者实现也比较简单,后者稍微麻烦了一些,感兴趣可以自己分析。

  最后切入正题,看看滑动Button要如何实现呢?首先看一下效果图:

 图1-1
  
 图1-2

  图1-1所示的滑动Button实现的思路是这样的,背景图片有开和关的文字,一个按钮在其上面左右滑动,遮住相应的部分,使其在一个位置时候只能看到一个开关。


  如图1-3,在实现的时候,先画一个开关背景图片只,然后在其上面画一个按钮,滑动开关的时候对上面的按钮进行处理即可。

  准备:
    1、按钮图片
       
      

    2、背景图片       

       
 编码:

    在自定义滑动按钮控件的时候,可以有多种选择,可以继承于Button,也可以继承于Button的子类,也可以继承于View类等。我们知道滑动按钮是 一个很简单的控件,就是左右滑动改变显示内容,不需要其他的额外东西在里面,所以直接继承于View来实现即可。如果继承于系统的一些控件,那么有很多东 西用不到,会造成浪费。

    1、定义一个类继承于View,初始化构造方法,在构造方法中加载图片及其信息。

    2、重写onMeasure()方法,计算控件的大小。

    3、重写onTouchEvent()方法,对滑动事件进行判别处理。

    4、定义接口,实现回调。

    5、重写onDraw()方法,动态画出按钮。

代码如下:
/**
*
*/
package com.kince.slidebutton;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
* @author kince
* @category 左右手势滑动button
* @serial 1.0.0
* @since 2014.5.17
* @see http://blog.csdn.net/wangjinyu501
*
*/
public class SlideButton extends View {

  private Bitmap slideBitMap;// 滑动图片
  private Bitmap switchBitMap;// 背景图片

  private int slideBitMapWidth;// 滑动图片宽度
  private int switchBitMapWidth;// 背景图片宽度
  private int switchBitMapHeight;// 背景图片高度

  private boolean currentState;// 开关状态
  private boolean isSliding = false; // 是否正在滑动中

  private int currentX; // 当前开关的位置

  private OnToggleStateChangedListener mChangedListener;// 回调接口

  /**
  * @param context
  *		  在java代码中直接调用使用此构造方法
  */
  public SlideButton(Context context) {
    this(context, null);
    // TODO Auto-generated constructor stub
  }

  /**
  * @param context
  * @param attrs
  *		  在xml中使用要用到这个方法
  */
  public SlideButton(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
    // TODO Auto-generated constructor stub
  }

  /**
  * @param context
  * @param attrs
  * @param defStyleAttr
  *		  指定一个样式
  */
  public SlideButton(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initBitmap();
  }

  /**
  * @category 加载背景图片以及开关图片 然后获取各自的宽高
  *
  */
  private void initBitmap() {
    // TODO Auto-generated method stub
    slideBitMap = BitmapFactory.decodeResource(getResources(),
        R.drawable.slide_button_background);
    switchBitMap = BitmapFactory.decodeResource(getResources(),
        R.drawable.switch_background);
    slideBitMapWidth = slideBitMap.getWidth();
    switchBitMapWidth = switchBitMap.getWidth();
    switchBitMapHeight = switchBitMap.getHeight();
    Log.i("switchBitMapWidth", switchBitMapWidth + "");
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // TODO Auto-generated method stub
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    setMeasuredDimension(switchBitMapWidth, switchBitMapHeight);// 设置控件的宽高
  }

  @Override
  protected void onDraw(Canvas canvas) {
    // 绘制button背景图片
    canvas.drawBitmap(switchBitMap, 0, 0, null);
    // 绘制滑动开关
    if (isSliding) {// 如果当前状态是滑动中 则动态绘制开关
      int dis = currentX - slideBitMapWidth / 2;
      if (dis < 0) {
        dis = 0;
      } else if (dis > switchBitMapWidth - slideBitMapWidth) {
        dis = switchBitMapWidth - slideBitMapWidth;
      }
      canvas.drawBitmap(slideBitMap, dis, 0, null);
    } else {
      if (currentState) { // 绘制开关为开的状态
        canvas.drawBitmap(slideBitMap, switchBitMapWidth
            - slideBitMapWidth, 0, null);
      } else { // 绘制开关为关的状态
        canvas.drawBitmap(slideBitMap, 0, 0, null);
      }
    }
    super.onDraw(canvas);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    // 手势识别 判断滑动方向
    int action = event.getAction();
    switch (action) {
    case MotionEvent.ACTION_DOWN:
      isSliding = true;
      currentX = (int) event.getX();
      break;

    case MotionEvent.ACTION_MOVE:
      currentX = (int) event.getX();
      Log.i("currentX", currentX + "");

      break;
    case MotionEvent.ACTION_UP:
      isSliding = false;
      int bgCenter = switchBitMapWidth / 2;
      boolean state = currentX > bgCenter; // 改变后的状态
      if (state != currentState && mChangedListener != null) {// 添加回调
        mChangedListener.onToggleStateChanged(state);
      }
      currentState = state;
      break;
    default:
      break;
    }
    invalidate();
    return true;
  }

  public OnToggleStateChangedListener getmChangedListener() {
    return mChangedListener;
  }

  public void setmChangedListener(
      OnToggleStateChangedListener mChangedListener) {
    this.mChangedListener = mChangedListener;
  }

  public boolean isToggleState() {
    return currentState;
  }

  public void setToggleState(boolean currentState) {
    this.currentState = currentState;
  }

}
  回调接口,
package com.kince.slidebutton;

/**
 * @author kince
 *
 */
public interface OnToggleStateChangedListener {

     /**
      * @category
      * @param state
      */
     public void onToggleStateChanged(boolean state);

}
  Activity代码,
package com.kince.slidebutton;

import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import android.os.Build;

public class MainActivity extends ActionBarActivity {

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

    if (savedInstanceState == null) {
      getSupportFragmentManager().beginTransaction()
          .add(R.id.container, new PlaceholderFragment()).commit();
    }
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
      return true;
    }
    return super.onOptionsItemSelected(item);
  }

  /**
  * A placeholder fragment containing a simple view.
  */
  public static class PlaceholderFragment extends Fragment implements
      OnToggleStateChangedListener {

    private SlideButton slidebutton;

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
      View rootView = inflater.inflate(R.layout.fragment_main, container,
          false);
      slidebutton = (SlideButton) rootView.findViewById(R.id.slidebutton1);
      // 设置一下开关的状态
      slidebutton.setToggleState(true); // 设置开关的状态为打开
      slidebutton.setmChangedListener(this);
      return rootView;
    }

    @Override
    public void onToggleStateChanged(boolean state) {
      // TODO Auto-generated method stub
      FragmentActivity activity = getActivity();
      if (state) {
        Toast.makeText(activity, "开关打开", 0).show();
      } else {
        Toast.makeText(activity, "开关关闭", 0).show();
      }
    }
  }

}

  未完待续。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。