一、 效果图
二、 实现原理
一个View,画一个圆角矩形,再画一个圆点就可以了,100行代码左右就可以了,不需要图片。
三、 实现代码
为了代码不臃肿,只添加了一个设置默认开关的方法,就没添加设置颜色的方法,如果需要的话自己根据项目在源码里面设置即可,解析我都写在源码里面了。
SwitchView.java
package tpnet.switchview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* 作用: 开关View
*
* @author LITP
* @date 2016/10/26
*/
public class SwitchView extends View implements View.OnClickListener {
private boolean isOpen = false; //开关,默认为关
private Paint paintPrev; //圆点画笔
private Paint paintBack; //背景画笔
//关闭时候的背景颜色
private int colorClose = Color.parseColor("#888888");
//开启时候的背景颜色
private int colorOpen = Color.parseColor("#32CD32");
private int xPrev = 0; //圆的圆心x坐标
private int yPrev; //圆的圆心y坐标
private int radiusPrev; //圆的半径
/**
* 在布局文件使用该类,将会用这个构造方法来实例化该类
* @param context
* @param attrs
*/
public SwitchView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init(){
paintPrev = new Paint();
paintBack = new Paint();
//关闭锯齿
paintPrev.setAntiAlias(true);
paintBack.setAntiAlias(true);
//设置圆点颜色
paintPrev.setColor(Color.parseColor("#ffffff"));
paintBack.setColor(colorClose);
this.setOnClickListener(this);
}
/*
* ------一个视图从创建到显示过程中的主要方法流程--------
*
* 1. 构造方法
*
* 2. 测量measure(int,int) --> onMeasure()
* 如果是ViewGroup还有义务测量孩子,孩子有建议权多高.
* serMeasuredDimension(width,height) 保存计算结果
*
* 3. 指定位置layout() --> onLayout();
* 指定控件的位置,一般View不用重写这个方法,ViewGroup是否才需要
*
* 4. 绘制视图 draw() --> onDraw(canvas);
* 根据上面两个方法参数进行绘制,
*
* invalidate()重绘制,导致onDraw执行
* */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//保存高度
//setMeasuredDimension(100, 50);
if(isOpen){//开的时候圆的圆心x坐标
xPrev = getMeasuredWidth() - getMeasuredHeight() /2;
}else{ //关的时候圆的圆心x坐标
xPrev = getMeasuredHeight() / 2;
}
yPrev = getMeasuredHeight() / 2; //圆的圆心y坐标
radiusPrev = getMeasuredHeight() / 2; //圆的半径
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int roundHeight = getMeasuredHeight();
//画圆角矩形背景
RectF rectF = new RectF(0, 0, getMeasuredWidth(), roundHeight);
canvas.drawRoundRect(rectF,roundHeight/2,roundHeight/2,paintBack);
//画圆点
canvas.drawCircle(xPrev, yPrev, radiusPrev-2, paintPrev);
}
/**
* 设置默认开关的状态,用在activity启动时候设置
* @param flag 是否为开启状态
*/
public void setDefaultSwitchState(boolean flag){
//默认为假的,所以为真才设置
if(flag){
paintBack.setColor(colorOpen);
isOpen = true;
}
}
/**
* 程序运行时候代码设置开关
*/
public void setSwitchState(boolean flag){
if(!((flag && isOpen) || (!flag && !isOpen) )){
onClick(this);
}
}
@Override
public void onClick(View view) {
if (isOpen) {
xPrev = getMeasuredHeight() / 2; //关闭时候 圆的圆心x坐标
paintBack.setColor(colorClose);
}else{
xPrev = getMeasuredWidth() - xPrev; //开启时候 圆的圆心x坐标
paintBack.setColor(colorOpen);
}
isOpen = !isOpen;
listener.onSwitch(isOpen);
//重新绘制
invalidate();
}
public interface OnSwitchListener{
/**
* 开关回调接口
* @param isOpen
*/
void onSwitch(boolean isOpen);
}
private OnSwitchListener listener;
public void setOnSwitchListener(OnSwitchListener listener){
this.listener = listener;
}
}
四、 使用
布局文件:
<tpnet.switchview.SwitchView
android:id="@+id/sw_message"
android:layout_width="50dp"
android:layout_height="30dp" />
activity里面:
swMessage = (SwitchView) findViewById(R.id.sw_message);
//swMessage.setDefaultSwitchState(true);
swMessage.setOnSwitchListener(new SwitchView.OnSwitchListener() {
@Override
public void onSwitch(boolean isOpen) {
tvTip.setText(isOpen?"开":"关");
}
});
就这么简单,谢谢大家,对你有用记得点一下顶。