自定义Switch开关控件
*做安卓也有一年多了*,一直想去学习**自定义控件**这一块(其实是自己懒–!),最近闲下来看了很多关于自定义控件方面的东西,虽然不是很熟练,但是基本上能去弄清楚它的实现方式有哪些。。也自己试着去模仿别人的代码做了一些自定义的控件,其中就有接下来我要写的自定义Switch控件,做的不好请大家见谅–!(大神勿喷)
好了废话不多说直接上效果图!
[开起](https://img-blog.csdn.net/20170224133316287?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzQ4NzQwNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)![关闭](https://img-blog.csdn.net/20170224133352866?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzQ4NzQwNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
没有动图工具,懒得做了,效果很简单。。开启和关闭颜色可以自己去设定。。。做自定义控件有几步去走,只要思路清晰了,剩下的就是实现的方法了。
1. 自定义控件的第一步
在arr文件中去配置自己控件里的所用到的属性(你也可以定死–!,但是为了不重复造轮子,你懂得)
配置文件代码如下
` <declare-styleable name="MySwitchButton">
<attr name="themeColor2" format="color"/>
<attr name="isOpen2" format="boolean"/>
</declare-styleable>`<br/>
2. 自定义控件的第二步
在自定义view中获取这些值
` */
public MySwitchButton(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setAntiAlias(true);
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.MySwitchButton);
isOpen =typedArray.getBoolean(R.styleable.MySwitchButton_isOpen2,false);
theme_color =typedArray.getColor(R.styleable.MySwitchButton_themeColor2, Color.GREEN);
typedArray.recycle();
}
3. 自定义控件第三步
在onMeasure()方法中去测量现在的控件大小` /**
* 自定义控件第二步,在onMeasure方法中去计算控件的宽高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureDimension(widthMeasureSpec,280);
int height =measureDimension(heightMeasureSpec,140);
if (width<height){
width = height * 2;
}
setMeasuredDimension(width,height);
initView();
}
/**
* 封装测量的代码 减少代码冗余
*/
private int measureDimension(int Measure,int defuldim){
int result;
int mode = MeasureSpec.getMode(Measure);
int size = MeasureSpec.getSize(Measure);
if (mode==MeasureSpec.EXACTLY){
result =size;
}else {
result =defuldim;
if (mode==MeasureSpec.AT_MOST){
result=Math.min(result, size);
}
}
return result;
}
/**
* 在onMeasure方法中去初始化变量,画笔等
*/
public void initView(){
int width =getMeasuredWidth();
int height =getMeasuredHeight();
backRect = new Rect();
circleRect = new Rect();
backRectF = new RectF();
circleRectF = new RectF();
backRect.set(0,0,width,height);
min_left =MIN_SIZE;
max_left =width -(height-2*MIN_SIZE)-MIN_SIZE;
if (isOpen){
circle_left =max_left;
alpha=255;
}else {
alpha=0;
circle_left=MIN_SIZE;
}
left_begin =circle_left;
}`
4. 自定义控件第三步
在onDraw方法中把按钮绘制出来
'/**
* 自定义控件第三步,在ondraw方法中绘制
*/
@Override
protected void onDraw(Canvas canvas) {
int radius;
radius = backRect.height() / 2;
paint.setColor(Color.GRAY);
backRectF.set(backRect);
canvas.drawRoundRect(backRectF, radius, radius, paint);
paint.setColor(theme_color);
paint.setAlpha(alpha);
canvas.drawRoundRect(backRectF, radius, radius, paint);
circleRect.set(circle_left, MIN_SIZE, circle_left
+ backRect.height() - 2 * MIN_SIZE, backRect.height()
- MIN_SIZE);
circleRectF.set(circleRect);
paint.setColor(Color.WHITE);
canvas.drawRoundRect(circleRectF, radius, radius, paint);
}
5. 第五步
在onThouch方法中监听手势
/**
* 自定义控件第三步,在onThouch方法里写滑动事件
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = MotionEventCompat.getActionMasked(event);
switch (action) {
case MotionEvent.ACTION_DOWN:
eventStartX = (int) event.getRawX();
break;
case MotionEvent.ACTION_MOVE:
eventEndX = (int) event.getRawX();
diffX = eventEndX - eventStartX;
int tempX = diffX + left_begin;
tempX = (tempX > max_left ? max_left : tempX);
tempX = (tempX < min_left ? min_left : tempX);
if (tempX >= min_left && tempX <= max_left) {
circle_left = tempX;
alpha = (int) (255 * (float) tempX / (float) max_left);
invalidateView();
}
break;
case MotionEvent.ACTION_UP:
int wholeX = (int) (event.getRawX() - eventStartX);
left_begin = circle_left;
boolean toRight;
toRight = (left_begin > max_left / 2 ? true : false);
if (Math.abs(wholeX) < 3) {
toRight = !toRight;
}
moveToDest(toRight);
break;
default:
break;
}
return true;
}
6. 第六步
写对外暴露的接口
public void setOnChangeListener(OnChangeListener onChangeListener){
this.onChangeListener =onChangeListener;
}
public interface OnChangeListener{
void changelistener(boolean flag);
}
然后大功告成 ,打完收工,具体的代码后面附上,虽然写的很粗糙,但是写完以后还是对自定义控件有了更深的理解,以后还会继续去尝试,谁让我还是个菜鸡呢···略略略–!
[戳这里](http://download.csdn.net/detail/u013487404/9762913%20%E6%88%B3%E8%BF%99%E9%87%8C)