public class WiperSwitch extends View {
private Bitmap selectedBitmap;//滑动选中开关的背景
private Bitmap uncheckedBitmap;//滑动未选中开关的背景
private Bitmap switchBitmap;//开关的背景
private Bitmap slidBitmap;//滑动块的图片对象
private int MAX_Left;//left的最大值
private int slidLeft ;//滑块left的值,默认为0
private boolean isOpen = false;//记录滑动开关的状态,默认为关闭,false
private OnCheckChangeListener mOnCheckChangeListener;//点击事件回调接口对象
private int startX;
private int moveX;//记录手指在控件上,x轴的移动
private boolean isClick ;//记录当前是否是点击事件
//在xml里面使用样式,创建该控件时,调用这个构造方法
public WiperSwitch(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
//在xml里面引用该控件时,就调用该构造方法
public WiperSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
String namespace = "http://schemas.android.com/apk/res-auto";
isOpen = attrs.getAttributeBooleanValue(namespace , "isOpen", false);
if (isOpen) {
slidLeft = MAX_Left;
}else{
slidLeft = 0;
}
int slidBitmapId = attrs.getAttributeResourceValue(namespace, "slidBitmap", -1);
if (slidBitmapId > -1) {
slidBitmap = BitmapFactory.decodeResource(getResources(), slidBitmapId);
}
int selectedBitmapId = attrs.getAttributeResourceValue(namespace, "selectedImage", -1);
if (slidBitmapId > -1) {
selectedBitmap = BitmapFactory.decodeResource(getResources(), selectedBitmapId);
}
int uncheckedBitmapId = attrs.getAttributeResourceValue(namespace, "uncheckedImage", -1);
if (slidBitmapId > -1) {
uncheckedBitmap = BitmapFactory.decodeResource(getResources(), uncheckedBitmapId);
}
init();
invalidate();
}
//当该控件,使用代码创建的时间,调用该构造方法
public WiperSwitch(Context context) {
super(context);
init();
}
//初始化方法
private void init() {
if (isOpen)
switchBitmap = selectedBitmap;
else
switchBitmap = uncheckedBitmap;
MAX_Left = (int) (switchBitmap.getWidth() - (slidBitmap.getWidth()*1.25f));
if (isOpen){
slidLeft = MAX_Left;
}else{
slidLeft = 0;
}
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (isClick) {//点击事件
if (isOpen) {//如果开则关闭
System.out.println("关闭");
isOpen = false;
slidLeft = 0;
switchBitmap = uncheckedBitmap;
}else{//如果关则打开
System.out.println("打开");
isOpen = true;
slidLeft = MAX_Left;
switchBitmap = selectedBitmap;
}
//重新调用ondraw方法
invalidate();//强制view进行重绘操作,重新调用ondraw方法
// isOpen = !isOpen;
if (mOnCheckChangeListener != null) {
mOnCheckChangeListener.onCheckChanged(WiperSwitch.this, isOpen);
}
}
}
});
}
//测量方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(switchBitmap.getWidth(), switchBitmap.getHeight());
}
//绘制方法
/**
* Canvas 画布:把控件绘制在画布,才能显示到屏幕上
*/
@Override
protected void onDraw(Canvas canvas) {
// canvas.drawRect(0, 0, 200, 200, paint );
canvas.drawBitmap(switchBitmap, 0, 0, null);
canvas.drawBitmap(slidBitmap, slidLeft, 0, null);
}
public void setOnCheckChangeListener(OnCheckChangeListener listener){
this.mOnCheckChangeListener = listener;
}
//滑动开关 的点击事件回调接口
public interface OnCheckChangeListener{
public void onCheckChanged(View v,boolean isOpen);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//1、记录手指按下的起始点
startX = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
//2、记录手指移动后的结束点
int endX = (int) event.getX();
//3、计算出移动间距
int diffX = endX -startX;
moveX = moveX + Math.abs(diffX);
//4、更新slidleft的值
slidLeft += diffX;
// slidLeft = slidLeft + diffX;
if (slidLeft < 0) {//设置左边界
slidLeft = 0;
}
if (slidLeft > MAX_Left) {//设置右边界
slidLeft = MAX_Left;
}
//5、重绘控件
invalidate();
//6、更新起始点
startX = endX;
break;
case MotionEvent.ACTION_UP:
if (moveX > 5) {//手指移动的间距大于5个像素,就认为是一个滑动事件
isClick = false;
}else{//手指移动的间距小于5个像素,就认为是一个点击事件
isClick = true;
}
moveX = 0;
if (!isClick) {//如果是滑动事件
//计算出中心线
int center = MAX_Left/2;
if (slidLeft > center) {//大于中心线的话,就显示为打开
isOpen = true;
slidLeft = MAX_Left;
switchBitmap = selectedBitmap;
}else{//小于中心线的话,就显示为关闭
isOpen = false;
slidLeft = 0;
switchBitmap = uncheckedBitmap;
}
invalidate();
//手指抬起后,将状态值返回给主界面
if (mOnCheckChangeListener != null) {
mOnCheckChangeListener.onCheckChanged(WiperSwitch.this, isOpen);
}
}
invalidate();
break;
default:
break;
}
return super.onTouchEvent(event);//自己去消费触摸事件
}
}
/*********************** Style *********************/
<declare-styleable name="WiperSwitch">
<attr name="slidBitmap" format="reference" />
<attr name="selectedImage" format="reference" />
<attr name="uncheckedImage" format="reference" />
<attr name="isOpen" format="boolean" />
</declare-styleable>
/*********************** Xml *********************/
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.wiperswitchview.MainActivity">
<com.wiperswitchview.view.WiperSwitch
app:isOpen="true"
app:slidBitmap="@drawable/action_btn"
app:selectedImage="@drawable/action_on"
app:uncheckedImage="@drawable/action_off"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/switchbtn"
/>
</RelativeLayout>
/*********************** MainActivity*********************/
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WiperSwitch wiperSwitch = (WiperSwitch) findViewById(R.id.switchbtn);
wiperSwitch.setOnCheckChangeListener(new WiperSwitch.OnCheckChangeListener() {
@Override
public void onCheckChanged(View v, boolean isOpen) {
if (isOpen){
Toast.makeText(MainActivity.this,"开",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(MainActivity.this,"关",Toast.LENGTH_SHORT).show();
}
}
});
}
}
转载于:https://blog.51cto.com/11808583/1795109