zoukankan      html  css  js  c++  java
  • Android SwitchButton(滑动开关)

    版本号:1.0
    日期:2014.5.17 2014.6.1
    版权:© 2014 kince 转载注明出处

      在介绍SwitchButton之前。先来看一下系统Button是怎样实现的。源代码例如以下:
    @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类等。我们知道滑动按钮是一个非常easy的控件,就是左右滑动改变显示内容,不须要其它的额外东西在里面。所以直接继承于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();
                   }
              }
         }
    
    }
    
      未完待续。


















    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    【LeetCode】13. Roman to Integer (2 solutions)
    【LeetCode】16. 3Sum Closest
    【LeetCode】18. 4Sum (2 solutions)
    【LeetCode】168. Excel Sheet Column Title
    如何应用性能测试常用计算公式
    系统吞吐量(TPS)、用户并发量、性能测试概念和公式
    Monkey测试3——Monkey测试结果分析
    Monkey测试2——Monkey测试策略
    Monkey测试1——Monkey的使用
    TestNG 三 测试方法
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4639244.html
Copyright © 2011-2022 走看看