SwitchView安卓自定义控件--切换开关

来源:互联网 发布:外国人看淘宝 编辑:程序博客网 时间:2024/05/16 17:54

安卓自定义控件需要关注View类中的以下三个方法,Measure(测量)-----Layout(布局)----Draw(绘制)。当时安卓官方不建议直接去复写这三个方法,而是提供了onMeasure,onLayout,onDraw三个方法供开发者使用。

言归正传,今天我这里需要自定义一个开关控件SwitchView。这不是一个ViewGroup,所以不需要考虑onLayout方法。重点是onMeasure和onDraw方法的开发。

开关控件主要由两张图片绘制而成,另外辅以一些逻辑动作事件。所以在初始化控件时先获取并解析图片资源:

BitmapFactory.decodeResource(getContext().getResources(), R.mipmap.switch_background);

自定义开法的控件,需要先复写onMeasure方法,告诉父控件自己的实际大小。该方法中又提供了一下方法,用来向父类提出自己的大小需求:

setMeasuredDimension(widthSpec, heightSpec);//widthSpec, heightSpec是控件显示的宽度和高度
控件的宽度和高度可以由图片资源解析成的Bitmap对象的getWidth(),getHeight()方法获取。

测量完自己的大小后,接下来需要复写绘制方法onDraw()展示控件的形状:

canvas.drawBitmap(switcherBitmap, 0, 0, paint);

         第一个参数表示需要绘制的bitmap图片,第二个参数表示自定义的控件距离父控件的左边距,第三个参数表示距离父控件的上边距。因为控件不同触摸动作会有不同形状,所以在每个触摸动作都需要重新调用onDraw方法绘制。

public boolean onTouchEvent(MotionEvent event) {    switch (event.getAction()) {        case MotionEvent.ACTION_DOWN:            downX = event.getX();            status = STATUS_DOWN;            invalidate();            break;        case MotionEvent.ACTION_MOVE:            downX = event.getX();            status=STATUS_MOVE;            invalidate();            break;        case MotionEvent.ACTION_UP:            status=STATUS_UP;            downX=event.getX();            if(downX<backgroundWidth/2f){                isOpened=false;                Log.i(TAG, "onTouchEvent: "+isOpened);            }else{                isOpened=true;                Log.i(TAG, "onTouchEvent: "+isOpened);            }            if(onSwitchListener!=null){                onSwitchListener.onSwitch(isOpened);            }            invalidate();            break;    }    return true;}
invalidate()方法会自动调用自己的onDraw()方法,另外还有postInvalidate()方法,也有同样的功能,所不同的是前者是在主线程中调用;后者是在子线程中调用。另外开关的状态是由接口回调传递出来。

对于不同的触摸点,绘制的形状不同,绘制代码如下所示:

@Overrideprotected void onDraw(Canvas canvas) {    if (backgroundBitmap != null) {        canvas.drawBitmap(backgroundBitmap, 0, 0, paint);    }    switch (status) {        case STATUS_MOVE://移动时开关布局随着手指移动        case STATUS_DOWN://按下时开关布局随着手指移动                float left = downX - switcherWidth / 2f;                if (left < 0) {//限制左边界                    left = 0;                }else if(downX>backgroundWidth-switcherWidth/2f){//限制右边界                    left=backgroundWidth-switcherWidth;                }                canvas.drawBitmap(switcherBitmap, left, 0, paint);            break;        case STATUS_UP:        case STATUS_INIT://手指离开控件时,控件要么绘制在开的状态,要么绘制在关的状态            if (switcherBitmap != null) {                if (!isOpened) {                    canvas.drawBitmap(switcherBitmap, 0, 0, paint);                } else {                    canvas.drawBitmap(switcherBitmap, backgroundWidth-switcherWidth, 0, paint);                }            }            break;        default:            break;    }}
最终的效果图如下所示:


另附上我的github仓库地址,有需要的朋友可以自行下载:

https://github.com/JemyZou/SwitchView




 




1 0
原创粉丝点击