仿iosswitch
2016-01-04 15:44:05 krubo1 阅读数 328

该篇文章从eoeAndroid搬迁过来的,原文地址:仿IOS Switch控件

前几天写了一个仿ios的segmentcontrol控件( 仿 ios segmentcontrol ),今天突然兴致来了,就写了一个仿ios 的switch控件,由于本人不是学习ps的,所以从ios上截取的图片可能不太完美,希望各位能够见谅。

废话不多少,上代码: 首先是得到自定义的属性,也就一个自定义的属性,就是控件的内容,默认值是on和off,可以在XML文件中引用,填写值的时候需要把打开写在前面,关闭写在后面,并用分号(:)隔开,如(开:关),注意分号是英文的分号。

public SwitchButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        this.context = context;
        TypedArray typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.SwitchButton);
        onOffString = typedArray.getString(R.styleable.SwitchButton_onOff);
        if (onOffString != null && (!"".equals(onOffString))) {
            String[] contentStr = onOffString.split(";");
            if (contentStr.length >= 2) {
                onString = "".equals(contentStr[0]) ? "on" : contentStr[0];
                offString = "".equals(contentStr[1]) ? "off" : contentStr[1];
            } else if (contentStr.length == 1) {
                onString = "".equals(contentStr[0]) ? "on" : contentStr[0];
                offString = "off";
            } else {
                onString = "on";
                offString = "off";
            }
        } else {
            onString = "on";
            offString = "off";
        }
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.view_switchbutton, this);
        switchLayout = (RelativeLayout) findViewById(R.id.switch_layout);
        switchOnBgTextView = (TextView) findViewById(R.id.switch_on_bg_textview);
        switchOffBgTextView = (TextView) findViewById(R.id.switch_off_bg_textview);
        switchOnButtonTextView = (TextView) findViewById(R.id.switch_on_button_textview);
        switchOffButtonTextView = (TextView) findViewById(R.id.switch_off_button_textview);
        switchOnButtonTextView.setTextColor(Color.WHITE);
        switchOnButtonTextView.setText(onString);
        switchOffButtonTextView.setTextColor(Color.GRAY);
        switchOffButtonTextView.setText(offString);
        switchLayout.setOnClickListener(this);
        setView();
    }

然后就是不同的点击事件展示不同的图片

private void setView() {
        if (switchStatues) {
            switchOnBgTextView.setVisibility(View.VISIBLE);
            switchOnButtonTextView.setVisibility(View.VISIBLE);
            switchOffBgTextView.setVisibility(View.GONE);
            switchOffButtonTextView.setVisibility(View.GONE);
        } else {
            switchOnBgTextView.setVisibility(View.GONE);
            switchOnButtonTextView.setVisibility(View.GONE);
            switchOffBgTextView.setVisibility(View.VISIBLE);
            switchOffButtonTextView.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.switch_layout:
            switchStatues = !switchStatues;
            setView();
            onCheckedChangeListener.onCheckedChange(switchStatues);
            break;

        default:
            break;
        }
    }

最后附上switch的布局

代码中的点击事件和得到当前的状态

button.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChange(boolean isChecked) {
                // TODO Auto-generated method stub
                if (isChecked) {
                    text.setText("开");
                } else {
                    text.setText("关");
                }
            }
        });
button.getSwitchStatues()

这里写图片描述 这里写图片描述

下载地址:项目代码

2018-12-19 17:01:00 weixin_33778544 阅读数 35

效果如下:


2962875-11e052419f20946f.png
image.png
<com.qiyuan.gamesdk.core.ui.dialog.biz.View.SwitchButton
            android:id="@+id/switch_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp" />

        <com.qiyuan.gamesdk.core.ui.dialog.biz.View.SwitchButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            app:sb_checked="true" />


        <com.qiyuan.gamesdk.core.ui.dialog.biz.View.SwitchButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            app:sb_checked="true"
            app:sb_show_indicator="false" />

        com.qiyuan.gamesdk.core.ui.dialog.biz.View.SwitchButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            app:sb_checked="true"
            app:sb_checked_color="#fdc951" />

        <com.qiyuan.gamesdk.core.ui.dialog.biz.View.SwitchButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            app:sb_background="#FFF"
            app:sb_button_color="#db99c7"
            app:sb_checked_color="#A36F95"
            app:sb_checkline_color="#a5dc88"
            app:sb_shadow_color="#A36F95"
            app:sb_uncheckcircle_color="#A36F95" />

        <com.qiyuan.gamesdk.core.ui.dialog.biz.View.SwitchButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            app:sb_enable_effect="false" />

主要核心代码(就两个文件)
SwitchButton.java

package com.qiyuan.gamesdk.core.ui.dialog.biz.View;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Checkable;

import com.qiyuan.gamesdk.R;


/**
 * SwitchButton.
 */
public class SwitchButton extends View implements Checkable {
    private static final int DEFAULT_WIDTH = dp2pxInt(58);
    private static final int DEFAULT_HEIGHT = dp2pxInt(36);

    /**
     * 动画状态:
     * 1.静止
     * 2.进入拖动
     * 3.处于拖动
     * 4.拖动-复位
     * 5.拖动-切换
     * 6.点击切换
     * **/
    private final int ANIMATE_STATE_NONE = 0;
    private final int ANIMATE_STATE_PENDING_DRAG = 1;
    private final int ANIMATE_STATE_DRAGING = 2;
    private final int ANIMATE_STATE_PENDING_RESET = 3;
    private final int ANIMATE_STATE_PENDING_SETTLE = 4;
    private final int ANIMATE_STATE_SWITCH = 5;

    public SwitchButton(Context context) {
        super(context);
        init(context, null);
    }

    public SwitchButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public SwitchButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public SwitchButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }

    @Override
    public final void setPadding(int left, int top, int right, int bottom) {
        super.setPadding(0, 0, 0, 0);
    }

    /**
     * 初始化参数
     */
    private void init(Context context, AttributeSet attrs) {

        TypedArray typedArray = null;
        if(attrs != null){
            typedArray = context.obtainStyledAttributes(attrs, R.styleable.SwitchButton);
        }

        shadowEffect = optBoolean(typedArray,
                R.styleable.SwitchButton_sb_shadow_effect,
                true);

        uncheckCircleColor = optColor(typedArray,
                R.styleable.SwitchButton_sb_uncheckcircle_color,
                0XffAAAAAA);//0XffAAAAAA;

        uncheckCircleWidth = optPixelSize(typedArray,
                R.styleable.SwitchButton_sb_uncheckcircle_width,
                dp2pxInt(1.5f));//dp2pxInt(1.5f);

        uncheckCircleOffsetX = dp2px(10);

        uncheckCircleRadius = optPixelSize(typedArray,
                R.styleable.SwitchButton_sb_uncheckcircle_radius,
                dp2px(4));//dp2px(4);

        checkedLineOffsetX = dp2px(4);
        checkedLineOffsetY = dp2px(4);

        shadowRadius = optPixelSize(typedArray,
                R.styleable.SwitchButton_sb_shadow_radius,
                dp2pxInt(2.5f));//dp2pxInt(2.5f);

        shadowOffset = optPixelSize(typedArray,
                R.styleable.SwitchButton_sb_shadow_offset,
                dp2pxInt(1.5f));//dp2pxInt(1.5f);

        shadowColor = optColor(typedArray,
                R.styleable.SwitchButton_sb_shadow_color,
                0X33000000);//0X33000000;

        uncheckColor = optColor(typedArray,
                R.styleable.SwitchButton_sb_uncheck_color,
                0XffDDDDDD);//0XffDDDDDD;

        checkedColor = optColor(typedArray,
                R.styleable.SwitchButton_sb_checked_color,
                0Xff51d367);//0Xff51d367;

        borderWidth = optPixelSize(typedArray,
                R.styleable.SwitchButton_sb_border_width,
                dp2pxInt(1));//dp2pxInt(1);

        checkLineColor = optColor(typedArray,
                R.styleable.SwitchButton_sb_checkline_color,
                Color.WHITE);//Color.WHITE;

        checkLineWidth = optPixelSize(typedArray,
                R.styleable.SwitchButton_sb_checkline_width,
                dp2pxInt(1f));//dp2pxInt(1.0f);

        checkLineLength = dp2px(6);

        int buttonColor = optColor(typedArray,
                R.styleable.SwitchButton_sb_button_color,
                Color.WHITE);//Color.WHITE;

        int effectDuration = optInt(typedArray,
                R.styleable.SwitchButton_sb_effect_duration,
                300);//300;

        isChecked = optBoolean(typedArray,
                R.styleable.SwitchButton_sb_checked,
                false);

        showIndicator = optBoolean(typedArray,
                R.styleable.SwitchButton_sb_show_indicator,
                true);

        background = optColor(typedArray,
                R.styleable.SwitchButton_sb_background,
                Color.WHITE);//Color.WHITE;

        enableEffect = optBoolean(typedArray,
                R.styleable.SwitchButton_sb_enable_effect,
                true);

        if(typedArray != null){
            typedArray.recycle();
        }


        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        buttonPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        buttonPaint.setColor(buttonColor);

        if(shadowEffect){
            buttonPaint.setShadowLayer(
                    shadowRadius,
                    0, shadowOffset,
                    shadowColor);
        }


        viewState = new ViewState();
        beforeState = new ViewState();
        afterState = new ViewState();

        valueAnimator = ValueAnimator.ofFloat(0f, 1f);
        valueAnimator.setDuration(effectDuration);
        valueAnimator.setRepeatCount(0);

        valueAnimator.addUpdateListener(animatorUpdateListener);
        valueAnimator.addListener(animatorListener);

        super.setClickable(true);
        this.setPadding(0, 0, 0, 0);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            setLayerType(LAYER_TYPE_SOFTWARE, null);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        if(widthMode == MeasureSpec.UNSPECIFIED
                || widthMode == MeasureSpec.AT_MOST){
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(DEFAULT_WIDTH, MeasureSpec.EXACTLY);
        }
        if(heightMode == MeasureSpec.UNSPECIFIED
                || heightMode == MeasureSpec.AT_MOST){
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(DEFAULT_HEIGHT, MeasureSpec.EXACTLY);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);


        float viewPadding = Math.max(shadowRadius + shadowOffset, borderWidth);

        height = h - viewPadding - viewPadding;
        width = w - viewPadding - viewPadding;

        viewRadius = height * .5f;
        buttonRadius = viewRadius - borderWidth;

        left = viewPadding;
        top = viewPadding;
        right = w - viewPadding;
        bottom = h - viewPadding;

        centerX = (left + right) * .5f;
        centerY = (top + bottom) * .5f;

        buttonMinX = left + viewRadius;
        buttonMaxX = right - viewRadius;

        if(isChecked()){
            setCheckedViewState(viewState);
        }else{
            setUncheckViewState(viewState);
        }

        isUiInited = true;

        postInvalidate();

    }

    /**
     * @param viewState
     */
    private void setUncheckViewState(ViewState viewState){
        viewState.radius = 0;
        viewState.checkStateColor = uncheckColor;
        viewState.checkedLineColor = Color.TRANSPARENT;
        viewState.buttonX = buttonMinX;
    }

    /**
     * @param viewState
     */
    private void setCheckedViewState(ViewState viewState){
        viewState.radius = viewRadius;
        viewState.checkStateColor = checkedColor;
        viewState.checkedLineColor = checkLineColor;
        viewState.buttonX = buttonMaxX;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        paint.setStrokeWidth(borderWidth);
        paint.setStyle(Paint.Style.FILL);
        //绘制白色背景
        paint.setColor(background);
        drawRoundRect(canvas,
                left, top, right, bottom,
                viewRadius, paint);
        //绘制关闭状态的边框
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(uncheckColor);
        drawRoundRect(canvas,
                left, top, right, bottom,
                viewRadius, paint);

        //绘制小圆圈
        if(showIndicator){
            drawUncheckIndicator(canvas);
        }

        //绘制开启背景色
        float des = viewState.radius * .5f;//[0-backgroundRadius*0.5f]
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(viewState.checkStateColor);
        paint.setStrokeWidth(borderWidth + des * 2f);
        drawRoundRect(canvas,
                left + des, top + des, right - des, bottom - des,
                viewRadius, paint);

        //绘制按钮左边绿色长条遮挡
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(1);
        drawArc(canvas,
                left, top,
                left + 2 * viewRadius, top + 2 * viewRadius,
                90, 180, paint);
        canvas.drawRect(
                left + viewRadius, top,
                viewState.buttonX, top + 2 * viewRadius,
                paint);

        //绘制小线条
        if(showIndicator){
            drawCheckedIndicator(canvas);
        }

        //绘制按钮
        drawButton(canvas, viewState.buttonX, centerY);
    }


    /**
     * 绘制选中状态指示器
     * @param canvas
     */
    protected void drawCheckedIndicator(Canvas canvas) {
        drawCheckedIndicator(canvas,
                viewState.checkedLineColor,
                checkLineWidth,
                left + viewRadius - checkedLineOffsetX, centerY - checkLineLength,
                left + viewRadius - checkedLineOffsetY, centerY + checkLineLength,
                paint);
    }


    /**
     * 绘制选中状态指示器
     * @param canvas
     * @param color
     * @param lineWidth
     * @param sx
     * @param sy
     * @param ex
     * @param ey
     * @param paint
     */
    protected void drawCheckedIndicator(Canvas canvas,
                                        int color,
                                        float lineWidth,
                                        float sx, float sy, float ex, float ey,
                                        Paint paint) {
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(color);
        paint.setStrokeWidth(lineWidth);
        canvas.drawLine(
                sx, sy, ex, ey,
                paint);
    }

    /**
     * 绘制关闭状态指示器
     * @param canvas
     */
    private void drawUncheckIndicator(Canvas canvas) {
        drawUncheckIndicator(canvas,
                uncheckCircleColor,
                uncheckCircleWidth,
                right - uncheckCircleOffsetX, centerY,
                uncheckCircleRadius,
                paint);
    }


    /**
     * 绘制关闭状态指示器
     * @param canvas
     * @param color
     * @param lineWidth
     * @param centerX
     * @param centerY
     * @param radius
     * @param paint
     */
    protected void drawUncheckIndicator(Canvas canvas,
                                        int color,
                                        float lineWidth,
                                        float centerX, float centerY,
                                        float radius,
                                        Paint paint) {
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(color);
        paint.setStrokeWidth(lineWidth);
        canvas.drawCircle(centerX, centerY, radius, paint);
    }

    /**
     * @param canvas
     * @param left
     * @param top
     * @param right
     * @param bottom
     * @param startAngle
     * @param sweepAngle
     * @param paint
     */
    private void drawArc(Canvas canvas,
                         float left, float top,
                         float right, float bottom,
                         float startAngle, float sweepAngle,
                         Paint paint){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            canvas.drawArc(left, top, right, bottom,
                    startAngle, sweepAngle, true, paint);
        }else{
            rect.set(left, top, right, bottom);
            canvas.drawArc(rect,
                    startAngle, sweepAngle, true, paint);
        }
    }

    /**
     * @param canvas
     * @param left
     * @param top
     * @param right
     * @param bottom
     * @param backgroundRadius
     * @param paint
     */
    private void drawRoundRect(Canvas canvas,
                               float left, float top,
                               float right, float bottom,
                               float backgroundRadius,
                               Paint paint){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            canvas.drawRoundRect(left, top, right, bottom,
                    backgroundRadius, backgroundRadius, paint);
        }else{
            rect.set(left, top, right, bottom);
            canvas.drawRoundRect(rect,
                    backgroundRadius, backgroundRadius, paint);
        }
    }


    /**
     * @param canvas
     * @param x px
     * @param y px
     */
    private void drawButton(Canvas canvas, float x, float y) {
        canvas.drawCircle(x, y, buttonRadius, buttonPaint);

        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(1);
        paint.setColor(0XffDDDDDD);
        canvas.drawCircle(x, y, buttonRadius, paint);
    }

    @Override
    public void setChecked(boolean checked) {
        if(checked == isChecked()){
            postInvalidate();
            return;
        }
        toggle(enableEffect, false);
    }

    @Override
    public boolean isChecked() {
        return isChecked;
    }

    @Override
    public void toggle() {
        toggle(true);
    }

    /**
     * 切换状态
     * @param animate
     */
    public void toggle(boolean animate) {
        toggle(animate, true);
    }

    private void toggle(boolean animate, boolean broadcast) {
        if(!isEnabled()){return;}

        if(isEventBroadcast){
            throw new RuntimeException("should NOT switch the state in method: [onCheckedChanged]!");
        }
        if(!isUiInited){
            isChecked = !isChecked;
            if(broadcast){
                broadcastEvent();
            }
            return;
        }

        if(valueAnimator.isRunning()){
            valueAnimator.cancel();
        }

        if(!enableEffect || !animate){
            isChecked = !isChecked;
            if(isChecked()){
                setCheckedViewState(viewState);
            }else{
                setUncheckViewState(viewState);
            }
            postInvalidate();
            if(broadcast){
                broadcastEvent();
            }
            return;
        }

        animateState = ANIMATE_STATE_SWITCH;
        beforeState.copy(viewState);

        if(isChecked()){
            //切换到unchecked
            setUncheckViewState(afterState);
        }else{
            setCheckedViewState(afterState);
        }
        valueAnimator.start();
    }

    /**
     *
     */
    private void broadcastEvent() {
        if(onCheckedChangeListener != null){
            isEventBroadcast = true;
            onCheckedChangeListener.onCheckedChanged(this, isChecked());
        }
        isEventBroadcast = false;
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(!isEnabled()){return false;}
        int actionMasked = event.getActionMasked();

        switch (actionMasked){
            case MotionEvent.ACTION_DOWN:{
                isTouchingDown = true;
                touchDownTime = System.currentTimeMillis();
                //取消准备进入拖动状态
                removeCallbacks(postPendingDrag);
                //预设100ms进入拖动状态
                postDelayed(postPendingDrag, 100);
                break;
            }
            case MotionEvent.ACTION_MOVE:{
                float eventX = event.getX();
                if(isPendingDragState()){
                    //在准备进入拖动状态过程中,可以拖动按钮位置
                    float fraction = eventX / getWidth();
                    fraction = Math.max(0f, Math.min(1f, fraction));

                    viewState.buttonX = buttonMinX
                            + (buttonMaxX - buttonMinX)
                            * fraction;

                }else if(isDragState()){
                    //拖动按钮位置,同时改变对应的背景颜色
                    float fraction = eventX / getWidth();
                    fraction = Math.max(0f, Math.min(1f, fraction));

                    viewState.buttonX = buttonMinX
                            + (buttonMaxX - buttonMinX)
                            * fraction;

                    viewState.checkStateColor = (int) argbEvaluator.evaluate(
                            fraction,
                            uncheckColor,
                            checkedColor
                    );
                    postInvalidate();

                }
                break;
            }
            case MotionEvent.ACTION_UP:{
                isTouchingDown = false;
                //取消准备进入拖动状态
                removeCallbacks(postPendingDrag);

                if(System.currentTimeMillis() - touchDownTime <= 300){
                    //点击时间小于300ms,认为是点击操作
                    toggle();
                }else if(isDragState()){
                    //在拖动状态,计算按钮位置,设置是否切换状态
                    float eventX = event.getX();
                    float fraction = eventX / getWidth();
                    fraction = Math.max(0f, Math.min(1f, fraction));
                    boolean newCheck = fraction > .5f;
                    if(newCheck == isChecked()){
                        pendingCancelDragState();
                    }else{
                        isChecked = newCheck;
                        pendingSettleState();
                    }
                }else if(isPendingDragState()){
                    //在准备进入拖动状态过程中,取消之,复位
                    pendingCancelDragState();
                }
                break;
            }
            case MotionEvent.ACTION_CANCEL:{
                isTouchingDown = false;

                removeCallbacks(postPendingDrag);

                if(isPendingDragState()
                        || isDragState()){
                    //复位
                    pendingCancelDragState();
                }
                break;
            }
        }
        return true;
    }


    /**
     * 是否在动画状态
     * @return
     */
    private boolean isInAnimating(){
        return animateState != ANIMATE_STATE_NONE;
    }

    /**
     * 是否在进入拖动或离开拖动状态
     * @return
     */
    private boolean isPendingDragState(){
        return animateState == ANIMATE_STATE_PENDING_DRAG
                || animateState == ANIMATE_STATE_PENDING_RESET;
    }

    /**
     * 是否在手指拖动状态
     * @return
     */
    private boolean isDragState(){
        return animateState == ANIMATE_STATE_DRAGING;
    }

    /**
     * 设置是否启用阴影效果
     * @param shadowEffect true.启用
     */
    public void setShadowEffect(boolean shadowEffect) {
        if(this.shadowEffect == shadowEffect){return;}
        this.shadowEffect = shadowEffect;

        if(this.shadowEffect){
            buttonPaint.setShadowLayer(
                    shadowRadius,
                    0, shadowOffset,
                    shadowColor);
        }else{
            buttonPaint.setShadowLayer(
                    0,
                    0, 0,
                    0);
        }
    }

    public void setEnableEffect(boolean enable){
        this.enableEffect = enable;
    }

    /**
     * 开始进入拖动状态
     */
    private void pendingDragState() {
        if(isInAnimating()){return;}
        if(!isTouchingDown){return;}

        if(valueAnimator.isRunning()){
            valueAnimator.cancel();
        }

        animateState = ANIMATE_STATE_PENDING_DRAG;

        beforeState.copy(viewState);
        afterState.copy(viewState);

        if(isChecked()){
            afterState.checkStateColor = checkedColor;
            afterState.buttonX = buttonMaxX;
            afterState.checkedLineColor = checkedColor;
        }else{
            afterState.checkStateColor = uncheckColor;
            afterState.buttonX = buttonMinX;
            afterState.radius = viewRadius;
        }

        valueAnimator.start();
    }


    /**
     * 取消拖动状态
     */
    private void pendingCancelDragState() {
        if(isDragState() || isPendingDragState()){
            if(valueAnimator.isRunning()){
                valueAnimator.cancel();
            }

            animateState = ANIMATE_STATE_PENDING_RESET;
            beforeState.copy(viewState);

            if(isChecked()){
                setCheckedViewState(afterState);
            }else{
                setUncheckViewState(afterState);
            }
            valueAnimator.start();
        }
    }


    /**
     * 动画-设置新的状态
     */
    private void pendingSettleState() {
        if(valueAnimator.isRunning()){
            valueAnimator.cancel();
        }

        animateState = ANIMATE_STATE_PENDING_SETTLE;
        beforeState.copy(viewState);

        if(isChecked()){
            setCheckedViewState(afterState);
        }else{
            setUncheckViewState(afterState);
        }
        valueAnimator.start();
    }


    @Override
    public final void setOnClickListener(OnClickListener l) {}

    @Override
    public final void setOnLongClickListener(OnLongClickListener l) {}

    public void setOnCheckedChangeListener(OnCheckedChangeListener l){
        onCheckedChangeListener = l;
    }

    public interface OnCheckedChangeListener{
        void onCheckedChanged(SwitchButton view, boolean isChecked);
    }

    /*******************************************************/
    private static float dp2px(float dp){
        Resources r = Resources.getSystem();
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
    }

    private static int dp2pxInt(float dp){
        return (int) dp2px(dp);
    }

    private static int optInt(TypedArray typedArray,
                              int index,
                              int def) {
        if(typedArray == null){return def;}
        return typedArray.getInt(index, def);
    }


    private static float optPixelSize(TypedArray typedArray,
                                      int index,
                                      float def) {
        if(typedArray == null){return def;}
        return typedArray.getDimension(index, def);
    }

    private static int optPixelSize(TypedArray typedArray,
                                    int index,
                                    int def) {
        if(typedArray == null){return def;}
        return typedArray.getDimensionPixelOffset(index, def);
    }

    private static int optColor(TypedArray typedArray,
                                int index,
                                int def) {
        if(typedArray == null){return def;}
        return typedArray.getColor(index, def);
    }

    private static boolean optBoolean(TypedArray typedArray,
                                      int index,
                                      boolean def) {
        if(typedArray == null){return def;}
        return typedArray.getBoolean(index, def);
    }
    /*******************************************************/


    /**
     * 阴影半径
     */
    private int shadowRadius;
    /**
     * 阴影Y偏移px
     */
    private int shadowOffset;
    /**
     * 阴影颜色
     */
    private int shadowColor ;

    /**
     * 背景半径
     */
    private float viewRadius;
    /**
     * 按钮半径
     */
    private float buttonRadius;

    /**
     * 背景高
     */
    private float height ;
    /**
     * 背景宽
     */
    private float width;
    /**
     * 背景位置
     */
    private float left   ;
    private float top    ;
    private float right  ;
    private float bottom ;
    private float centerX;
    private float centerY;

    /**
     * 背景底色
     */
    private int background;
    /**
     * 背景关闭颜色
     */
    private int uncheckColor;
    /**
     * 背景打开颜色
     */
    private int checkedColor;
    /**
     * 边框宽度px
     */
    private int borderWidth;

    /**
     * 打开指示线颜色
     */
    private int checkLineColor;
    /**
     * 打开指示线宽
     */
    private int checkLineWidth;
    /**
     * 打开指示线长
     */
    private float checkLineLength;
    /**
     * 关闭圆圈颜色
     */
    private int uncheckCircleColor;
    /**
     *关闭圆圈线宽
     */
    private int uncheckCircleWidth;
    /**
     *关闭圆圈位移X
     */
    private float uncheckCircleOffsetX;
    /**
     *关闭圆圈半径
     */
    private float uncheckCircleRadius;
    /**
     *打开指示线位移X
     */
    private float checkedLineOffsetX;
    /**
     *打开指示线位移Y
     */
    private float checkedLineOffsetY;


    /**
     * 按钮最左边
     */
    private float buttonMinX;
    /**
     * 按钮最右边
     */
    private float buttonMaxX;

    /**
     * 按钮画笔
     */
    private Paint buttonPaint;
    /**
     * 背景画笔
     */
    private Paint paint;

    /**
     * 当前状态
     */
    private ViewState viewState;
    private ViewState beforeState;
    private ViewState afterState;

    private RectF rect = new RectF();
    /**
     * 动画状态
     */
    private int animateState = ANIMATE_STATE_NONE;

    /**
     *
     */
    private ValueAnimator valueAnimator;

    private final android.animation.ArgbEvaluator argbEvaluator
            = new android.animation.ArgbEvaluator();

    /**
     *是否选中
     */
    private boolean isChecked;
    /**
     * 是否启用动画
     */
    private boolean enableEffect;
    /**
     * 是否启用阴影效果
     */
    private boolean shadowEffect;
    /**
     * 是否显示指示器
     */
    private boolean showIndicator;
    /**
     * 收拾是否按下
     */
    private boolean isTouchingDown = false;
    /**
     *
     */
    private boolean isUiInited = false;
    /**
     *
     */
    private boolean isEventBroadcast = false;

    private OnCheckedChangeListener onCheckedChangeListener;

    /**
     * 手势按下的时刻
     */
    private long touchDownTime;

    private Runnable postPendingDrag = new Runnable() {
        @Override
        public void run() {
            if(!isInAnimating()){
                pendingDragState();
            }
        }
    };

    private ValueAnimator.AnimatorUpdateListener animatorUpdateListener
            = new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float value = (Float) animation.getAnimatedValue();
            switch (animateState) {
                case ANIMATE_STATE_PENDING_SETTLE: {
                }
                case ANIMATE_STATE_PENDING_RESET: {
                }
                case ANIMATE_STATE_PENDING_DRAG: {
                    viewState.checkedLineColor = (int) argbEvaluator.evaluate(
                            value,
                            beforeState.checkedLineColor,
                            afterState.checkedLineColor
                    );

                    viewState.radius = beforeState.radius
                            + (afterState.radius - beforeState.radius) * value;

                    if(animateState != ANIMATE_STATE_PENDING_DRAG){
                        viewState.buttonX = beforeState.buttonX
                                + (afterState.buttonX - beforeState.buttonX) * value;
                    }

                    viewState.checkStateColor = (int) argbEvaluator.evaluate(
                            value,
                            beforeState.checkStateColor,
                            afterState.checkStateColor
                    );

                    break;
                }
                case ANIMATE_STATE_SWITCH: {
                    viewState.buttonX = beforeState.buttonX
                            + (afterState.buttonX - beforeState.buttonX) * value;

                    float fraction = (viewState.buttonX - buttonMinX) / (buttonMaxX - buttonMinX);

                    viewState.checkStateColor = (int) argbEvaluator.evaluate(
                            fraction,
                            uncheckColor,
                            checkedColor
                    );

                    viewState.radius = fraction * viewRadius;
                    viewState.checkedLineColor = (int) argbEvaluator.evaluate(
                            fraction,
                            Color.TRANSPARENT,
                            checkLineColor
                    );
                    break;
                }
                default:
                case ANIMATE_STATE_DRAGING: {
                }
                case ANIMATE_STATE_NONE: {
                    break;
                }
            }
            postInvalidate();
        }
    };

    private Animator.AnimatorListener animatorListener
            = new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            switch (animateState) {
                case ANIMATE_STATE_DRAGING: {
                    break;
                }
                case ANIMATE_STATE_PENDING_DRAG: {
                    animateState = ANIMATE_STATE_DRAGING;
                    viewState.checkedLineColor = Color.TRANSPARENT;
                    viewState.radius = viewRadius;

                    postInvalidate();
                    break;
                }
                case ANIMATE_STATE_PENDING_RESET: {
                    animateState = ANIMATE_STATE_NONE;
                    postInvalidate();
                    break;
                }
                case ANIMATE_STATE_PENDING_SETTLE: {
                    animateState = ANIMATE_STATE_NONE;
                    postInvalidate();
                    broadcastEvent();
                    break;
                }
                case ANIMATE_STATE_SWITCH: {
                    isChecked = !isChecked;
                    animateState = ANIMATE_STATE_NONE;
                    postInvalidate();
                    broadcastEvent();
                    break;
                }
                default:
                case ANIMATE_STATE_NONE: {
                    break;
                }
            }
        }

        @Override
        public void onAnimationCancel(Animator animation) {
        }

        @Override
        public void onAnimationRepeat(Animator animation) {
        }
    };


    /*******************************************************/
    /**
     * 保存动画状态
     * */
    private static class ViewState {
        /**
         * 按钮x位置[buttonMinX-buttonMaxX]
         */
        float buttonX;
        /**
         * 状态背景颜色
         */
        int checkStateColor;
        /**
         * 选中线的颜色
         */
        int checkedLineColor;
        /**
         * 状态背景的半径
         */
        float radius;
        ViewState(){}
        private void copy(ViewState source){
            this.buttonX = source.buttonX;
            this.checkStateColor = source.checkStateColor;
            this.checkedLineColor = source.checkedLineColor;
            this.radius = source.radius;
        }
    }

}

switch_button_attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="SwitchButton">
        <attr name="sb_shadow_radius" format="reference|dimension"/>
        <attr name="sb_shadow_offset" format="reference|dimension"/>
        <attr name="sb_shadow_color" format="reference|color"/>
        <attr name="sb_uncheck_color" format="reference|color"/>
        <attr name="sb_checked_color" format="reference|color"/>

        <attr name="sb_border_width" format="reference|dimension"/>
        <attr name="sb_checkline_color" format="reference|color"/>
        <attr name="sb_checkline_width" format="reference|dimension"/>
        <attr name="sb_uncheckcircle_color" format="reference|color"/>
        <attr name="sb_uncheckcircle_width" format="reference|dimension"/>
        <attr name="sb_uncheckcircle_radius" format="reference|dimension"/>

        <attr name="sb_checked" format="reference|boolean"/>
        <attr name="sb_shadow_effect" format="reference|boolean"/>
        <attr name="sb_effect_duration" format="reference|integer"/>
        <attr name="sb_button_color" format="reference|color"/>
        <attr name="sb_show_indicator" format="reference|boolean"/>
        <attr name="sb_background" format="reference|color"/>
        <attr name="sb_enable_effect" format="reference|boolean"/>
    </declare-styleable>
</resources>

直接将这两个文件拖到项目就可用了。

代码来自于
感谢:
Android 仿iOS Switch开关

2015-07-16 00:24:00 lyq_mufeng 阅读数 1566


       最近看见很多应用用这种仿IOS的开关控件,最近项目组也有要用到这个控件的需要,实际上最简单的方法是,直接让UI提供两张图片就可以了,分别代表打开和关闭的状态,但是UI实在是不给力,图片迟迟不到,所以,作为一个勤奋好学,自力更生的android程序员来说,好吧,果断自己自定义一个。

    其实,要实现这个功能,也不是很难,可以说非常easy。就是通过canvas画一个底层椭圆形的矩形,然后上面画一个开关的小圆圈,底层颜色和小圆圈所处位置根据开关状态不同显示。好了,先上图。



最后效果图就是这样的。代码如下:

package com.lyq.customSwitch;

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;
import android.view.View.OnClickListener;

/**
 * 仿IOS选择开关
 * @author mufeng
 *
 */
public class Switch extends View implements OnClickListener{

	private Context mContext;
	private Paint mPaint;
	private float width,height;
	private boolean isOpen=true;
	private RectF oval;

	public Switch(Context context) {
		super(context);
		init(context);
	}

	public Switch(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public Switch(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init(context);
	}

	public Switch(Context context, AttributeSet attrs, int defStyleAttr,
			int defStyleRes) {
		super(context, attrs, defStyleAttr, defStyleRes);
		init(context);
	}

	private void init(Context context) {
		mContext=context;
		//设置宽高 
		width=DensityUtils.dip2px(mContext, 80);
		height=width/2;
		mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		setOnClickListener(this);
		oval = new RectF(0, 0, width, height);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		
		//根据控件当前状态设置画笔颜色
		if(isOpen){
			mPaint.setColor(getResources().getColor(R.color.select));
		}else{
			mPaint.setColor(Color.GRAY);
		}
		mPaint.setStyle(Paint.Style.FILL);// 充满
		
		//画底层圆角矩形
		canvas.drawRoundRect(oval,height/2 , width/4, mPaint);// 第二个参数是x半径,第三个参数是y半径
		
		//画开关圆圈 将画笔颜色设为白色 
		mPaint.setColor(Color.WHITE);
		//根据控件当前状态判断将圆圈画在左边还是右边
		if(isOpen){
			canvas.drawCircle(width/4*3, height/2, height/2-DensityUtils.dip2px(mContext, 2), mPaint);
		}else{
			canvas.drawCircle(width/4, height/2, height/2-DensityUtils.dip2px(mContext, 2), mPaint);
		}
	}
	
	@Override  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
        //重新测量控件的大小,主要在控件宽高属性设置为wrap_content时,将控件大小设置为实际大小
		setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));  
    }  
  
	//测量宽度
    private int measureWidth(int measureSpec) {  
        int result = 0;  
        int specMode = MeasureSpec.getMode(measureSpec);  
        int specSize = MeasureSpec.getSize(measureSpec);  
  
        if (specMode == MeasureSpec.EXACTLY) {  
            result = specSize;  
        } else {  
            result = (int) DensityUtils.dip2px(mContext, 80) + getPaddingLeft() + getPaddingRight();  
            if (specMode == MeasureSpec.AT_MOST) {  
                result = Math.min(result, specSize);  
            }  
        }  
  
        return result;  
    }  
  
    //测量高度
    private int measureHeight(int measureSpec) {  
        int result = 0;  
        int specMode = MeasureSpec.getMode(measureSpec);  
        int specSize = MeasureSpec.getSize(measureSpec);  
  
        if (specMode == MeasureSpec.EXACTLY) {  
            result = specSize;  
        } else {  
            result = (int) DensityUtils.dip2px(mContext, 80)/2 + getPaddingTop() + getPaddingBottom();  
            if (specMode == MeasureSpec.AT_MOST) {  
                result = Math.min(result, specSize);  
            }  
        }
        return result;  
    }  
	
    /**
     * 点击切换isOpen值,调用postInvalidate重绘view,可用于异步线程
     */
	@Override
	public void onClick(View view) {
		isOpen=!isOpen;
		postInvalidate();
	}
	
	/**
	 * 打开控件开关
	 */
	public void open(){
		if(!isOpen){
			isOpen=true;
			postInvalidate();
		}
	}
	
	/**
	 * 关闭控件开关
	 */
	public void close(){
		if(isOpen){
			isOpen=false;
			postInvalidate();
		}
	}
	
	/**
	 * 获取控件状态
	 * @return 
	 */
	public boolean isOpen(){
		return isOpen;
	}
}

代码中各个方法都注释的比较详细,具体的我就不介绍了。最后附上项目源码

2018-04-18 12:01:00 weixin_34081595 阅读数 5

在style.xml中添加如下代码:
<style name="Switch">

<item name="android:track">@drawable/switch_track</item>

<item name="android:thumb">@drawable/abc_switch_thumb_material</item>
<item name="android:background">@null</item>

<item name="android:textOn"> </item>
<item name="android:textOff"> </item>

<item name="android:switchMinWidth">50dp</item>
</style>
在drawable/switch_tradck.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true">
<shape>
<solid android:color="#4dd664" />
<corners android:radius="30dp"/>
<size android:width="50dp" android:height="26dp" />
</shape>
</item>
<item android:state_checked="false">
<shape>
<solid android:color="#ffffff" />
<corners android:radius="30dp"/>

<size android:width="50dp" android:height="28dp" />

<stroke android:color="#e4e4e4" android:width="1dp" android:dashGap="0dp" android:dashWidth="0dp"/>
</shape>
</item>
</selector>
这样整个style就基本完成了,用起来也非常简单.
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Switch"/>

2017-06-15 18:50:12 qq_36854455 阅读数 97

百度了半天   最后  靠自己的修改加百度的知识   最终封装好   mark!!!!!!()

package myview;

/**
 * Created by DZy on 2017/3/22.
 */
import android.animation.ObjectAnimator;
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.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.Checkable;

public class Switchbutton extends View implements Checkable {

    private static final int FILL_COLOR_1 = Color.parseColor("#EEEEEE");
    private static final int FILL_COLOR_2 = Color.parseColor("#014d67");
    private static final int ANIMATION_DURATION = 200;
    private static final int OFFSET = 12;

    private ObjectAnimator processAnimator;
    private boolean isChecked;
    private float process = 0;
    private float lastX = 0;
    private float lastProcess = 0;
    private int fillColor;
    private boolean isPressed;
    private Paint cPaint;
    private Paint fPaint;
    private Paint mPaint;
    private RectF rectF = null;
    public Switchbutton(Context context) {
        super(context);
        init();
    }

    public Switchbutton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public Switchbutton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode  = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize  = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int width;
        int height;
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            //AT_MOST或者UNSPECIFIED,即用户没有指定宽度时,显示默认宽度
            width = dip2px(getContext(), 128);
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            //AT_MOST或者UNSPECIFIED,即用户没有指定高度时,显示默认高度
            height = dip2px(getContext(), 48);
        }
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawFrameRoundRect(canvas);
        drawRect(canvas);
        drawCircle(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return false;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = event.getX();
                lastProcess = getProcess();
                isPressed = true;
                break;
            case MotionEvent.ACTION_MOVE:
                setProcess(lastProcess + (event.getX() - lastX)/getWidth());
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                isPressed = false;
                if (lastX==event.getX())
                {
                    if (process == 0)
                    {
                        setProcess(1f);
                    }else if (process==1){
                        setProcess(0f);
                    }
                }else{
                    if (getProcess() > 0.5) {
                        setProcess(1f);
                    } else {
                        setProcess(0f);
                    }
                }
                break;
            default:
                break;
        }
        return true;
    }

    @Override
    public void setChecked(boolean b) {
        if (isChecked != b) {
            isChecked = b;
            animateSwitch(isChecked);
        }
    }

    @Override
    public boolean isChecked() {
        return isChecked;
    }

    @Override
    public void toggle() {
        setChecked(!isChecked);
    }

    /**
     * 初始化
     */
    private void init() {
        isPressed = false;
        isChecked = false;
        fillColor = FILL_COLOR_1;
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        initAnimation();
        initPaint();
//        this.setOnClickListener(new OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                if (process == 0)
//                {
//                    setProcess(1f);
//                }else if (process==1){
//                    setProcess(0f);
//                }
//            }
//        });
    }

    /**
     * 初始化动画对象
     */
    private void initAnimation() {
        processAnimator = ObjectAnimator.ofFloat(this, "process", 0, 1);
        processAnimator.setDuration(ANIMATION_DURATION);
        processAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
    }

    /**
     * 初始化画笔
     */
    private void initPaint() {

        //填充画笔
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(0);
        mPaint.setStyle(Paint.Style.FILL);

        //frame画笔
        fPaint = new Paint();
        fPaint.setAntiAlias(true);
        fPaint.setColor(Color.parseColor("#BDBDBD"));
        fPaint.setAlpha(255);
        fPaint.setStrokeWidth(1);
        fPaint.setStyle(Paint.Style.STROKE);

        //圆圈画笔
        cPaint = new Paint();
        cPaint.setAntiAlias(true);
        cPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        cPaint.setStrokeWidth(1);
        cPaint.setColor(Color.WHITE);
    }

    public float getProcess() {
        return process;
    }

    /**
     * 设置滑动的进度
     * @param process
     */
    public void setProcess(float process) {
        if (process >= 1f) {
            this.process = 1;
            isChecked = true;
        } else if (process <= 0f) {
            this.process = 0;
            isChecked = false;
        } else {
            this.process = process;
        }
        if (this.process > 0.5) {
            fillColor = FILL_COLOR_2;
        } else {
            fillColor = FILL_COLOR_1;
        }
       {
            if (process==0)
            {
                listener.onStateChanged(isChecked);
                Log.e( "setProcess: ",isChecked()+"" );
            }else if (process==1){
                Log.e( "setProcess: ",isChecked()+"" );
                listener.onStateChanged(isChecked);
            }
        }
        postInvalidate();


    }

    /**
     * 开关动画
     * @param checked
     */
    private void animateSwitch(boolean checked) {
        if (processAnimator.isRunning()) {
            processAnimator.cancel();
        }

        if (checked) {
            processAnimator.setFloatValues(process, 1f);
        } else {
            processAnimator.setFloatValues(process, 0f);
        }
        processAnimator.start();
    }

    /**
     * 获取滑动时的alpha     * @return
     */
    private int getColorAlpha() {
        int alpha;
        if (getProcess() >= 0 && getProcess() < 0.5) {
            alpha = (int) (255 * (1 - getProcess()));
        } else {
            alpha = (int) (255 * getProcess());
        }
        int colorAlpha = Color.alpha(fillColor);
        colorAlpha = colorAlpha * alpha / 255;
        return colorAlpha;
    }

    /**
     * 绘制填充的色值
     * @param canvas
     */
    private void drawRect(Canvas canvas) {
        mPaint.setARGB(getColorAlpha(), Color.red(fillColor), Color.green(fillColor), Color.blue(fillColor));
        if (rectF == null) {
            rectF = new RectF(OFFSET, OFFSET, getWidth()-OFFSET, getHeight()-OFFSET);
        }
        canvas.drawRoundRect(rectF, (getHeight() - OFFSET)/2, (getHeight() - OFFSET)/2, mPaint);
    }

    /**
     * 绘制边框线条
     * @param canvas
     */
    private void drawFrameRoundRect(Canvas canvas) {
        if (rectF == null) {
            rectF = new RectF(OFFSET, OFFSET, getWidth()-OFFSET, getHeight()-OFFSET);
        }
        canvas.drawRoundRect(rectF, (getHeight() - OFFSET)/2, (getHeight() - OFFSET)/2, fPaint);
    }

    /**
     * 绘制点击的原点
     * @param canvas
     */
    private void drawCircle(Canvas canvas) {
        if (isPressed) {
            cPaint.setShadowLayer(12, 0, 12, Color.argb(61, 0x00, 0x00, 0x00));
           canvas.drawCircle(getHeight()/2 + (getWidth() - getHeight())*process, getHeight()/2, (getHeight() - getHeight()/3)/2 + 6, cPaint);
        //    canvas.drawCircle(getHeight()/2 + (getWidth() - getHeight())*process, getHeight()/2,  (getHeight() - getHeight()/3)/2, cPaint);
        } else {
            cPaint.setShadowLayer(6, 0, 6, Color.argb(61, 0x00, 0x00, 0x00));
            canvas.drawCircle(getHeight()/2 + (getWidth() - getHeight())*process, getHeight()/2,  (getHeight() - getHeight()/3)/2, cPaint);
        }
    }

    /**
     * dip转换的px
     * @param context
     * @param dpValue
     * @return
     */
    private int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) ((dpValue * scale) + 0.5f);
    }

    public interface OnSwitchStateChangedListener {
        void onStateChanged(boolean state);
    }

    private OnSwitchStateChangedListener listener;
//            = new OnSwitchStateChangedListener() {
//        @Override
//        public void onStateChanged(boolean state) {
//            if (state)
//            {
//                Log.e( "onStateChanged: ","" );
//            }else{
//                Log.e( "onStateChanged: ","" );
//            }
//        }
//    };
    public void setOnSwitchStateChangedListener(OnSwitchStateChangedListener listener) {
        if (listener != null)
        {
            this.listener = listener;
        }
    }
}

没有更多推荐了,返回首页