Android自定义Switch开关

在Android4.0中也添加了一个类似的控件:Switch。如下图所示:

其类关系图如下:
Android自定义Switch开关_第1张图片
这种控件使用起来很简单,但有一定的局限性:
1. 必须在4.0以上的系统中才能使用
2. 原生的UI不太美观
因此,基于上面两点,自定义Switch成为了首选。
SwitchButton.java
package com.jackie.countdowntimer;

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

/**
 * Created by Jackie on 2015/12/15.
 */
public class SwitchButton extends View {
    private Bitmap mSwitchBackgroud, mSlideBackground;

    private int mCurrentX;  //当前X轴偏移量
    private boolean mCurrentState = false;  //当前状态,判断滑块是否滑动成功
    private boolean mIsSliding = false;    //滑块是否正在滑动

    private OnSwitchStateChangeListener mOnSwitchStateChangeListener; //状态改变的回调

    public SwitchButton(Context context, AttributeSet attrs) {
        super(context, attrs);

        initBitmap();
    }

    //初始化开关图片
    private void initBitmap() {
        mSwitchBackgroud = BitmapFactory.decodeResource(getResources(), R.drawable.switch_background);
        mSlideBackground = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button_background);
    }

    //设置当前控件的宽和高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // 设置开关的宽和高
        setMeasuredDimension(mSwitchBackgroud.getWidth(), mSwitchBackgroud.getHeight());
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //绘制背景
        canvas.drawBitmap(mSwitchBackgroud, 0, 0, null);

        if (mIsSliding) {  //正在滑动中
            int left = mCurrentX - mSlideBackground.getWidth();
            if (left < 0) {  //超过左边界
                left = 0;
            } else if (left > mSwitchBackgroud.getWidth() - mSlideBackground.getWidth()) { //超出右边界
                left = mSwitchBackgroud.getWidth() - mSlideBackground.getWidth();
            }

            canvas.drawBitmap(mSlideBackground, left, 0, null);
        } else {
            if (mCurrentState) {
                //绘制开关开的状态
                int left = mSwitchBackgroud.getWidth() - mSlideBackground.getWidth();
                canvas.drawBitmap(mSlideBackground, left, 0, null);
            } else {
                //绘制开关关的状态
                canvas.drawBitmap(mSlideBackground, 0, 0, null);
            }
        }

        super.onDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mCurrentX = (int) event.getX();
                mIsSliding = true;
                break;
            case MotionEvent.ACTION_MOVE:
                mCurrentX = (int) event.getX();
                break;
            case MotionEvent.ACTION_UP:
                mCurrentX = (int) event.getX();
                mIsSliding = false;

                int center = mSwitchBackgroud.getWidth() / 2;
                boolean state = mCurrentX > center;   //滑块滑动的距离超过背景的一半,表示滑动成功,状态需要改变

                if (mCurrentState != state && mOnSwitchStateChangeListener != null) {  //两个状态不一样,表示滑动已经滑动成功,状态改变
                    mOnSwitchStateChangeListener.onSwitchStateChange(state);
                }

                mCurrentState = state;
                break;
        }

        invalidate();
        return true;
    }

    /**
     * 设置开关的状态
     * @param state
     */
    public void setSwitchState(boolean state) {
        mCurrentState = state;
    }

    public void setOnSwitchStateChangeListener(OnSwitchStateChangeListener onSwitchStateChangeListener) {
        this.mOnSwitchStateChangeListener = onSwitchStateChangeListener;
    }
}

OnSwitchStateChangeListener.java

package com.jackie.countdowntimer;

/**
 * Created by Jackie on 2015/12/15.
 */
public interface OnSwitchStateChangeListener {
    /**
     * 当开关状态改变时回调此方法
     * @param state 开关当前的状态
     */
    void onSwitchStateChange(boolean state);
}
在xml中作如下定义:
<com.jackie.countdowntimer.SwitchButton
        android:id="@+id/switcher"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/verify_code"
        />
使用方法:
        mSwitchButton = (SwitchButton) findViewById(R.id.switcher);
        mSwitchButton.setSwitchState(true);
        mSwitchButton.setOnSwitchStateChangeListener(new OnSwitchStateChangeListener() {
            @Override
            public void onSwitchStateChange(boolean state) {
                if (state) {
                    Toast.makeText(MainActivity.this, "开关打开了", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "开关关闭了", Toast.LENGTH_SHORT).show();
                }
            }
        });
最后附上所用的资源图片:
   
效果图如下:
Android自定义Switch开关_第2张图片

你可能感兴趣的:(android,switch)