zoukankan      html  css  js  c++  java
  • 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();
          }
        }
      }
    
    }

      未完待续。

  • 相关阅读:
    记账本第二天
    记账本第一天
    HDU 1811
    Codeforces Round #246 (Div. 2) D. Prefixes and Suffixes
    KMP超强模板贴一份
    2014辽宁省赛总结
    Codeforces Round #244 (Div. 2)
    CodeForces 383D Antimatter
    NEU 1351 Goagain and xiaodao's romantic story I
    UVA 10692 Huge Mod
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4013826.html
Copyright © 2011-2022 走看看