效果图:
关状态 中间拖动 开开关
素材图片
关状态的背景图
开状态的背景图
拖动的按钮
下面就直接来看看代码吧:
一、自定义的一个控件:
一、自定义的一个控件:
package com.zhong.newswitch.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.zhong.newswitch.R;
public class SlideSwitch extends View {
private Bitmap imgOn;
private Bitmap imgOff;
private Bitmap imgBtn;
private float countX;
private int viewWidth;
private int viewHeight;
private OnSwitchStateChangListener listener;
private boolean switchState;
private boolean lastStaete;
//设置一个事件监听的方法
public void setOnSwitchStateChangListener(OnSwitchStateChangListener listener) {
this.listener = listener;
}
public SlideSwitch(Context context) {
super(context);
init(context, null, 0);
}
public SlideSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public SlideSwitch(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
//获取“开”的背景图片的BitMap对象
imgOn = BitmapFactory.decodeResource(getResources(), R.drawable.slide_bg_on);
//获取“关”的背景图片的BitMap对象
imgOff = BitmapFactory.decodeResource(getResources(), R.drawable.slide_bg_off);
//获取“按钮”的背景图片的BitMap对象
imgBtn = BitmapFactory.decodeResource(getResources(), R.drawable.slide_btn);
if (attrs!=null){
//获取到自定义的xml中的已经声明的属性 此处要使用自定义的xml中的name
TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.slide);
//获取自定义的第一项的属性,获取属性值当找不到时返回默认值,
boolean state = arr.getBoolean(0, false);
//释放资源
arr.recycle();
//直接调用设置初始的状态
setSwitchState(state);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//获取背景图片的高作为控件的高
viewWidth = imgOff.getWidth();
viewHeight = imgOff.getHeight();
//设置控件的宽高
setMeasuredDimension(viewWidth, viewHeight);
}
@Override
protected void onDraw(Canvas canvas) {
if (countX < imgBtn.getWidth() / 2) {
//判断不能移出外面
countX = imgBtn.getWidth() / 2;
}
if (countX > (imgOff.getWidth() - imgBtn.getWidth() / 2)) {
countX = imgOff.getWidth() - imgBtn.getWidth() / 2;
}
//当移动过了中间线左边时图片为关,在右边背景改为开的图片
if (countX < imgOff.getWidth() / 2) {
canvas.drawBitmap(imgOff, 0, 0, null);
} else {
canvas.drawBitmap(imgOn, 0, 0, null);
}
//绘制小按钮
canvas.drawBitmap(imgBtn, countX - imgBtn.getWidth() / 2 - 2, 0, null);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
countX = event.getX();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_UP:
//当手离开地没有在边上,判断后直接跳到边去
if (countX < viewWidth / 2) {
countX = imgBtn.getWidth() / 2;
switchState = false;
} else {
countX = imgOff.getWidth() - imgBtn.getWidth() / 2;
switchState = true;
}
//判断是否有监听如果没有设置监听不调用,判断现在的状态原先的状态是否一样,如果一样不调用
if (listener != null&&lastStaete!=switchState) {
listener.OnSwitchStateChang(switchState);
}
lastStaete = switchState;
break;
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
}
invalidate();
return true;
}
//添加一个可以设置选中状态的方法
public void setSwitchState(boolean state) {
lastStaete=state;
if (state){
countX = imgOff.getWidth() - imgBtn.getWidth() / 2;
}else{
countX = imgBtn.getWidth() / 2;
}
}
//添加一个开关事件的监听接口
public interface OnSwitchStateChangListener {
void OnSwitchStateChang(boolean state);
}
}
二、自定义一个第一在xml中用的属性
在res目录下键 res-values-slft_attrs.xml
<span style="color:#000000;"><?xml version="1.0" encoding="utf-8"?>
<!--自定义控件的属性-->
<resources>
<!--声明属性name必须有-->
<declare-styleable name="slide">
<!--name="state"属性名,format="boolean"属性类型-->
<attr name="state" format="boolean"></attr>
</declare-styleable>
</resources></span>
三、main.xml中的代码
<span style="color:#000000;"><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:my="http://schemas.android.com/apk/res/com.zhong.newswitch"
android:orientation="vertical"
android:background="#FFF"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!--com.zhong.newswitch为应用的包名-->
<com.zhong.newswitch.view.SlideSwitch
my:state="true"
android:id="@+id/switch_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout></span>
四 、MainActivity中的代码
<span style="color:#000000;">package com.zhong.newswitch;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import com.zhong.newswitch.view.SlideSwitch;
public class MainActivity extends Activity {
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SlideSwitch slideSwitch= (SlideSwitch) findViewById(R.id.switch_main);
//设置初始的状态
slideSwitch.setSwitchState(true);
//监听状态
slideSwitch.setOnSwitchStateChangListener(new SlideSwitch.OnSwitchStateChangListener() {
@Override
public void OnSwitchStateChang(boolean state) {
Toast.makeText(MainActivity.this, state+"",Toast.LENGTH_SHORT).show();
}
});
}
}</span>
ok了