public class WiperSwitchButton extends View implements OnTouchListener {
private Bitmap bg_on, bg_off, slipper_btn;
/**
* 按下时的x和当前的x
*/
private float downX, nowX;
/**
* 记录用户是否在滑动
*/
private boolean onSlip = false;
/**
* 当前的状态
*/
private boolean nowStatus = false;
/**
* 监听接口
*/
private OnChangedListener listener;
public WiperSwitchButton(Context context) {
super(context);
init();
}
public WiperSwitchButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public WiperSwitchButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
@Override
public void setLayoutParams(LayoutParams params) {
super.setLayoutParams(params);
params.width = bg_on.getScaledWidth(UIUtils.currentDisplayMetrics());
params.height = bg_on.getScaledHeight(UIUtils.currentDisplayMetrics());
super.setLayoutParams(params);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
if (event.getX() > bg_off.getScaledWidth(UIUtils.currentDisplayMetrics())
|| event.getY() > bg_off.getScaledHeight(UIUtils.currentDisplayMetrics())) {
return false;
} else {
onSlip = true;
downX = event.getX();
nowX = downX;
}
break;
}
case MotionEvent.ACTION_MOVE: {
nowX = event.getX();
break;
}
case MotionEvent.ACTION_UP: {
onSlip = false;
nowStatus = !nowStatus;
if (listener != null) {
listener.OnChanged(WiperSwitchButton.this, nowStatus);
}
break;
}
}
// 刷新界面
invalidate();
return true;
}
public void init() {
// 载入图片资源
bg_on = BitmapFactory.decodeResource(getResources(), R.drawable.on_btn);
bg_off = BitmapFactory.decodeResource(getResources(),
R.drawable.off_btn);
slipper_btn = BitmapFactory.decodeResource(getResources(),
R.drawable.bg_white);
setOnTouchListener(this);
}
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas);
Matrix matrix = new Matrix();
Paint paint = new Paint();
float x = 0;
if (!nowStatus) {
canvas.drawBitmap(bg_off, matrix, paint);// 画出关闭时的背景
} else {
canvas.drawBitmap(bg_on, matrix, paint);// 画出打开时的背景
}
if (onSlip) {// 是否是在滑动状态,
if (nowX >= bg_on.getScaledWidth(UIUtils.currentDisplayMetrics()))// 是否划出指定范围,不能让滑块跑到外头,必须做这个判断
x = bg_on.getScaledWidth(UIUtils.currentDisplayMetrics()) - slipper_btn.getScaledWidth(UIUtils.currentDisplayMetrics()) / 2;// 减去滑块1/2的长度
else
x = nowX - slipper_btn.getScaledWidth(UIUtils.currentDisplayMetrics()) / 2;
} else {
if (nowStatus) {// 根据当前的状态设置滑块的x值
x = bg_on.getScaledWidth(UIUtils.currentDisplayMetrics()) - slipper_btn.getScaledWidth(UIUtils.currentDisplayMetrics());
} else {
x = 0;
}
}
// 对滑块滑动进行异常处理,不能让滑块出界
if (x < 0) {
x = 0;
} else if (x > bg_on.getScaledWidth(UIUtils.currentDisplayMetrics()) - slipper_btn.getScaledWidth(UIUtils.currentDisplayMetrics())) {
x = bg_on.getScaledWidth(UIUtils.currentDisplayMetrics()) - slipper_btn.getScaledWidth(UIUtils.currentDisplayMetrics());
}
// 画出滑块
canvas.drawBitmap(slipper_btn, x, 0, paint);
}
/**
* 为WiperSwitch设置一个监听,供外部调用的方法
*
* @param listener
*/
public void setOnChangedListener(OnChangedListener listener) {
this.listener = listener;
}
/**
* 设置滑动开关的初始状态,供外部调用
*
* @param checked
*/
public void setChecked(boolean checked) {
if (checked) {
nowX = bg_off.getScaledWidth(UIUtils.currentDisplayMetrics());
} else {
nowX = 0;
}
//
nowStatus = checked;
//
invalidate();
}
/*
* 回调接口
*/
public interface OnChangedListener {
public void OnChanged(WiperSwitchButton wiperSwitch, boolean checkState);
}
protected int measureDimension( int defaultSize, int measureSpec ) {
int result = defaultSize;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
//1. layout给出了确定的值,比如:100dp
//2. layout使用的是match_parent,但父控件的size已经可以确定了,比如设置的是具体的值或者match_parent
if (specMode == MeasureSpec.EXACTLY) {
result = specSize; //建议:result直接使用确定值
}
//1. layout使用的是wrap_content
//2. layout使用的是match_parent,但父控件使用的是确定的值或者wrap_content
else if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(defaultSize, specSize); //建议:result不能大于specSize
}
//UNSPECIFIED,没有任何限制,所以可以设置任何大小
//多半出现在自定义的父控件的情况下,期望由自控件自行决定大小
else {
result = defaultSize;
}
return result;
}
}
使用时:
<pre name="code" class="java"> <包名.WiperSwitchButton
android:id="@+id/switch1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:layout_marginRight="16dp"
android:checked="true" />