滑动开关按钮的实现
自定义layout布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.xykj.xtogglebutton.MainActivity">
<com.xykj.view.XToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="50dp" />
<com.xykj.view.XToggleButton
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_marginTop="10dp"/>
</LinearLayout>
新建View类
public class XToggleButton extends View {
/**
* 提供两种构造
*
* @param context
*/
public XToggleButton(Context context) {
super(context);
init();
}
public XToggleButton(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
private int width;
private int radius;
private Point centerLeft;
private Point centerRight;
private Rect bgRect;
private Paint paint;
private boolean isOpen;
private Point thumbCenter;
private int thumbRadius;
private boolean isDragging;
private Point leftTextPoint;
private Point rightTextPoint;
private String openText = "开";
private String closeText = "关";
private static final int openColor = 0xFF303F9F;
private static final int closeColor = 0xff666666;
private void init() {
centerLeft = new Point();
centerRight = new Point();
thumbCenter = new Point();
leftTextPoint = new Point();
rightTextPoint = new Point();
bgRect = new Rect();
paint = new Paint();
paint.setAntiAlias(true);
}
private Rect textLeftRect = new Rect();
private Rect textRightRect = new Rect();
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
width = getDefaultSize(120, widthMeasureSpec);
int h = getDefaultSize(60, heightMeasureSpec);
int height = h;
if (h > width / 2) {
height = width / 2;
}
radius = height / 2;
centerLeft.set(radius, h / 2);
centerRight.set(width - radius, h / 2);
bgRect.set(centerLeft.x, centerLeft.y - radius, centerRight.x, centerLeft.y + radius);
if (isOpen) {
thumbCenter.set(centerRight.x, centerRight.y);
} else {
thumbCenter.set(centerLeft.x, centerLeft.y);
}
thumbRadius = radius - 5;
paint.setTextSize(thumbRadius);
paint.getTextBounds(openText, 0, openText.length(), textLeftRect);
paint.getTextBounds(closeText, 0, closeText.length(), textRightRect);
leftTextPoint.set(centerLeft.x - textLeftRect.centerX(), centerLeft.y - textLeftRect.centerY());
rightTextPoint.set(centerRight.x - textRightRect.centerX(), centerRight.y - textRightRect.centerY());
setMeasuredDimension(width, h);
}
public static int getDefaultSize(int size, int measureSpec) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
case MeasureSpec.AT_MOST:
result = size;
break;
case MeasureSpec.EXACTLY:
int specSize = MeasureSpec.getSize(measureSpec);
result = specSize;
break;
}
return result;
}
@Override
protected void onDraw(Canvas canvas) {
paint.setColor(isOpen ? openColor : closeColor);
canvas.drawCircle(centerLeft.x, centerLeft.y, radius, paint);
canvas.drawCircle(centerRight.x, centerRight.y, radius, paint);
canvas.drawRect(bgRect, paint);
if (isDragging) {
if (isOpen) {
drawText(canvas, true);
paint.setColor(closeColor);
canvas.drawCircle(centerRight.x, centerRight.y, thumbRadius, paint);
canvas.drawRect(thumbCenter.x, thumbCenter.y - thumbRadius, centerRight.x, thumbCenter.y + thumbRadius, paint);
} else {
drawText(canvas, false);
canvas.drawText(openText, leftTextPoint.x, leftTextPoint.y, paint);
paint.setColor(openColor);
canvas.drawCircle(centerLeft.x, centerLeft.y, thumbRadius, paint);
canvas.drawRect(centerLeft.x, centerLeft.y - thumbRadius, thumbCenter.x, centerLeft.y + thumbRadius, paint);
}
drawText(canvas, !isOpen);
} else {
drawText(canvas, isOpen);
}
paint.setColor(0xFF3F51B5);
canvas.drawCircle(thumbCenter.x, thumbCenter.y, thumbRadius, paint);
}
private void drawText(Canvas canvas, boolean open) {
if (open) {
paint.setColor(Color.WHITE);
canvas.drawText(openText, leftTextPoint.x, leftTextPoint.y, paint);
} else {
paint.setColor(Color.BLACK);
canvas.drawText(closeText, rightTextPoint.x, rightTextPoint.y, paint);
}
}
private int lastX;
private long downTime;
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
isDragging = true;
lastX = (int) event.getX();
downTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_MOVE:
if (isDragging) {
int currentX = (int) event.getX();
int x1 = currentX - lastX;
int nX = thumbCenter.x + x1;
if (nX < centerLeft.x) {
nX = centerLeft.x;
} else if (nX > centerRight.x) {
nX = centerRight.x;
}
thumbCenter.x = nX;
lastX = currentX;
invalidate();
}
break;
case MotionEvent.ACTION_UP:
long currentTime = System.currentTimeMillis();
long t = currentTime - downTime;
if (!isOpen) {
if (t <= 200) {
open();
} else if (isDragging) {
if (thumbCenter.x > width / 2) {
open();
} else {
thumbCenter.x = centerLeft.x;
}
}
} else {
if (t <= 200) {
close();
} else if (isDragging) {
if (thumbCenter.x < width / 2) {
close();
} else {
thumbCenter.x = centerRight.x;
}
}
}
isDragging = false;
invalidate();
break;
}
return true;
}
private void open() {
thumbCenter.x = centerRight.x;
isOpen = true;
}
private void close() {
thumbCenter.x = centerLeft.x;
isOpen = false;
}
}
效果如下图:
