自定义的三项开关控件

此控件是一个开关组件

一个三项开关

可以滑动

可以点击

可以自定义背景颜色

费话少说

接下来是使用说明,(源码放在文章最后)

从布局开始

<?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"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/blue"
    android:padding="20dp">

    <com.z.proxy.androidtest.SwitchZ
        android:id="@+id/switchz"
        android:layout_width="120dp"
        android:layout_height="40dp"
        app:radian="25sp"
        app:viewBgColor="#ffffff"
        app:defaultCircleColor="#999999"
        app:leftCircleColor="#Ea4a4a"
        app:midCircleColor="#ffc600"
        app:rightCircleColor="#239a1c"/>
</LinearLayout>

app:viewBgColor="#ffffff"
app:defaultCircleColor="#999999"
app:leftCircleColor="#Ea4a4a"
app:midCircleColor="#ffc600"
app:rightCircleColor="#239a1c"
从上到下依次代表的意思:背景边角弧度,圆的默认颜色,左边圆选中的颜色,中间圆选中的颜色,右边圆选中的颜色

组件包含一个attrs文件,直接上传attrs的内容

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="switch_style">
        <attr name="radian" format="dimension"/>
        <attr name="viewBgColor" format="color"/>
        <attr name="defaultCircleColor" format="color"/>
        <attr name="leftCircleColor" format="color"/>
        <attr name="midCircleColor" format="color"/>
        <attr name="rightCircleColor" format="color"/>
    </declare-styleable>
</resources>
然后就是牛逼的java代码了,(只是指java牛逼,我写的依然只能代表我是)
/**
 * 三项开关
 * Created by zhangxiaohui on 2017/3/17.
 */

public class SwitchZ extends View {
    private float viewWidth, viewHeight;

    private Paint bgPaint;//背景画笔
    private Paint circlePaint;//中间圆画笔
    private Paint textPaint;//写文字画笔
    private Paint imagePaint;//中间图片画笔
    private Paint moveCirclePaint;//移动效果画笔
    private Paint arrowPaint;//箭头画笔

    private int bgColor = Color.parseColor("#ffffff");//背景颜色
    private int textColor = Color.parseColor("#ffffff");//字体颜色
    private String arrowColor = "#e0e0e0";//默认箭头颜色

    private int normalColor = Color.parseColor("#999999");//未选中颜色
    private int leftSelectColor = Color.parseColor("#Ea4a4a");//左边选中颜色
    private int rightSelectColor = Color.parseColor("#239a1c");//右边选中颜色
    private int midSelectColor = Color.parseColor("#ffc600");//中间选中颜色
    private int circleColor = normalColor;//记录颜色

    private float circleRadian = 0f;//背景的弧度
    private float showCircleX = 0f;//当前界面显示的圆坐标X
    private float showCircleY = 0f;//当前界面显示的圆坐标Y
    private float showCircleRadian = 0f;//当前界面显示的圆的半径
    private float moveCircleX = 0f;
    private float moveCircleY = 0f;
    private float moveCircleRadian = 0f;

    private boolean isMove = false;

    private SWITCHBG switchbg = SWITCHBG.RIGHT;

    public SwitchZ(Context context) {
        this(context, null);
    }

    public SwitchZ(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.switch_style);
        circleRadian = a.getDimension(R.styleable.switch_style_radian, 70f);
        bgColor = a.getColor(R.styleable.switch_style_viewBgColor,Color.parseColor("#ffffff"));
        normalColor = a.getColor(R.styleable.switch_style_defaultCircleColor, Color.parseColor("#999999"));
        leftSelectColor = a.getColor(R.styleable.switch_style_leftCircleColor, Color.parseColor("#Ea4a4a"));
        midSelectColor = a.getColor(R.styleable.switch_style_midCircleColor, Color.parseColor("#ffc600"));
        rightSelectColor = a.getColor(R.styleable.switch_style_rightCircleColor, Color.parseColor("#239a1c"));
        a.recycle();

        init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.e("onDraw", "onDraw");
        RectF rectF = new RectF(0, 0, viewWidth, viewHeight);
        canvas.drawRoundRect(rectF, circleRadian, circleRadian, bgPaint);

        setDefaultCircleBackgroundColor(SWITCHBG.MID, canvas);
        setDefaultCircleBackgroundColor(SWITCHBG.LEFT, canvas);
        setDefaultCircleBackgroundColor(SWITCHBG.RIGHT, canvas);

        setCircleColor(switchbg);
        canvas.drawCircle(showCircleX, showCircleY, showCircleRadian, circlePaint);//默认选中圆上色

        float leftArrowX = (float) (viewWidth / 2.0 - (viewWidth / 2.0 * 2.0 / 6.0));
        float leftArrowY = viewHeight / 2 + circlePaint.getTextSize();
        float rightArrowX = (float) (viewWidth / 2.0 + (viewWidth / 2.0 / 5.0));
        float rightArrowY = leftArrowY;
        arrowPaint.setTextSize(viewHeight / 3);//arrowColor
        if(switchbg == SWITCHBG.LEFT){
            arrowPaint.setColor(leftSelectColor);
            canvas.drawText("<", leftArrowX, leftArrowY, arrowPaint);
            arrowPaint.setColor(Color.parseColor(arrowColor));
            canvas.drawText(">", rightArrowX, rightArrowY, arrowPaint);
        }else if(switchbg == SWITCHBG.RIGHT){
            arrowPaint.setColor(rightSelectColor);
            canvas.drawText(">", rightArrowX, rightArrowY, arrowPaint);
            arrowPaint.setColor(Color.parseColor(arrowColor));
            canvas.drawText("<", leftArrowX, leftArrowY, arrowPaint);
        }else {
            arrowPaint.setColor(Color.parseColor(arrowColor));
            canvas.drawText("<", leftArrowX, leftArrowY, arrowPaint);
            canvas.drawText(">", rightArrowX, rightArrowY, arrowPaint);
        }

        if (isMove) {
            canvas.drawCircle(moveCircleX, moveCircleY, moveCircleRadian, moveCirclePaint);//移动的圆
        }

        textPaint.setTextSize(viewHeight / 3);
        float leftTextX = viewWidth / 3 / 2 - textPaint.getTextSize() / 2;
        float leftTextY = viewHeight / 2 + textPaint.getTextSize() / 3;
        float rightTextX = viewWidth / 3 * 2 + (viewWidth - viewWidth / 3 * 2) / 2 - textPaint.getTextSize() / 2;
        float rightTextY = leftTextY;
        canvas.drawText("左", leftTextX, leftTextY, textPaint);
        canvas.drawText("右", rightTextX, rightTextY, textPaint);

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.point_switch_m);
        float imgX = viewWidth / 2 - bitmap.getWidth() / 2;// imagePaint.getTextSize() / 2
        float imgY = viewHeight / 2 - bitmap.getHeight() / 2;
//        int width = viewHeight / 3 * 2 / 3;
        canvas.drawBitmap(bitmap, imgX, imgY, imagePaint);//zoomImg(bitmap, width, width)
    }

    public static Bitmap zoomImg(Bitmap bm, int newWidth, int newHeight) {
        // 获得图片的宽高
        int width = bm.getWidth();
        int height = bm.getHeight();
        // 计算缩放比例
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片
        Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
        return newbm;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Log.e("onMeasure", "onMeasure");
        viewWidth = getMeasuredWidth();
        viewHeight = getMeasuredHeight();

        /**画圆初始赋值*/
        setCircleColor(SWITCHBG.MID);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 设置非选中圆的默认背景
     *
     * @param switchbg
     * @param canvas
     */
    private void setDefaultCircleBackgroundColor(SWITCHBG switchbg, Canvas canvas) {
        if (this.switchbg == switchbg) {
            return;
        }
        circleColor = normalColor;
        circlePaint.setColor(circleColor);
        switch (switchbg) {
            case LEFT:
                setCircleSize(SWITCHBG.LEFT);
                break;
            case MID:
                setCircleSize(SWITCHBG.MID);
                break;
            case RIGHT:
                setCircleSize(SWITCHBG.RIGHT);
                break;
        }

        canvas.drawCircle(showCircleX, showCircleY, showCircleRadian, circlePaint);//中间圆
    }

    private void setCircleColor(SWITCHBG switchbg) {
        switch (switchbg) {
            case LEFT:
                setCircleSize(SWITCHBG.LEFT);
                circleColor = leftSelectColor;
                break;
            case MID:
                setCircleSize(SWITCHBG.MID);
                circleColor = midSelectColor;
                break;
            case RIGHT:
                setCircleSize(SWITCHBG.RIGHT);
                circleColor = rightSelectColor;
                break;
        }
        circlePaint.setColor(circleColor);
        moveCirclePaint.setColor(circleColor);
    }

    /**
     * 设置圆大小及位置
     *
     * @param switchbg
     */
    private void setCircleSize(SWITCHBG switchbg) {
        switch (switchbg) {
            case LEFT:
                showCircleX = viewWidth / 3 / 2;
                showCircleY = viewHeight / 2;
                showCircleRadian = viewHeight / 3;
                break;
            case MID:
                float sideCircleCenter = viewHeight / 3;
                float midCircleCenter = sideCircleCenter * 2 / 3;
                showCircleX = viewWidth / 2;
                showCircleY = viewHeight / 2;
                showCircleRadian = midCircleCenter;
                break;
            case RIGHT:
                showCircleX = viewWidth / 3 * 2 + (viewWidth - (viewWidth / 3 * 2)) / 2;
                showCircleY = viewHeight / 2;
                showCircleRadian = viewHeight / 3;
                break;
        }
    }

    float downX;
    float downY;
    float upX;
    float upY;
    boolean outsideStart = false;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isMove = false;
                outsideStart = false;
                downX = event.getX();
                downY = event.getY();

                moveCircleY = viewHeight / 2;
                if (upX <= viewWidth / 3 && upX > 0 && upY <= viewHeight && upY > 0) {
//                    moveCircleX = viewWidth / 3 / 2;
                    moveCircleRadian = viewHeight / 3;
                } else if (upX > viewWidth / 3 && upX < viewWidth * 2 / 3 && upY > 0 && upY < viewHeight) {
//                    moveCircleX = viewWidth / 2;
                    moveCircleRadian = viewHeight / 3 * 2 / 3;
                } else if (upX > viewWidth * 2 / 3 && upX < viewWidth && upY > 0 && upY < viewHeight) {
//                    moveCircleX = viewWidth - viewHeight / 2;
                    moveCircleRadian = viewHeight / 3;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                isMove = true;
                outsideStart = false;
                upX = event.getX();
                upY = event.getY();
                if (downX < (showCircleX - showCircleRadian) || downX > (showCircleX + showCircleRadian)) {
                    outsideStart = true;
                    return true;
                }
                moveCircleX = event.getX();
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                isMove = false;
                if (outsideStart) {
                    return true;
                }
                upX = event.getX();
                upY = event.getY();
                outsideStart = false;
                if (upX <= viewWidth / 3 && upY <= viewHeight && upY > 0) {//左
                    showCircleX = viewWidth / 3 / 2;
                    showCircleY = viewHeight / 2;
                    showCircleRadian = viewHeight / 3;
                    switchbg = SWITCHBG.LEFT;
                    if (switchScrollListner != null) {
                        switchScrollListner.leftListner();
                    }
                } else if (upX > viewWidth / 3 && upX < viewWidth * 2 / 3 && upY > 0 && upY < viewHeight) {//中
                    showCircleX = viewWidth / 2;
                    showCircleY = viewHeight / 2;
                    showCircleRadian = viewHeight / 3 * 2 / 3;
                    switchbg = SWITCHBG.MID;
                    if (switchScrollListner != null) {
                        switchScrollListner.midListner();
                    }
                } else if (upX > viewWidth * 2 / 3 && upX < viewWidth * 2 && upY > 0 && upY < viewHeight) {//右
                    showCircleX = viewWidth / 3 * 2 + (viewWidth - (viewWidth / 3 * 2)) / 2;
                    showCircleY = viewHeight / 2;
                    showCircleRadian = viewHeight / 3;
                    switchbg = SWITCHBG.RIGHT;
                    if (switchScrollListner != null) {
                        switchScrollListner.rightListner();
                    }
                }
                invalidate();
                break;
        }
        return true;
    }

    private void init() {
        bgPaint = new Paint();
        bgPaint.setColor(bgColor);
        bgPaint.setStyle(Paint.Style.FILL);
        bgPaint.setAntiAlias(true);

        circlePaint = new Paint();
        circlePaint.setColor(circleColor);
        circlePaint.setAntiAlias(true);

        moveCirclePaint = new Paint();
        moveCirclePaint.setColor(circleColor);
        moveCirclePaint.setStyle(Paint.Style.FILL);
        moveCirclePaint.setAntiAlias(true);

        arrowPaint = new Paint();
        arrowPaint.setColor(circleColor);
        arrowPaint.setStyle(Paint.Style.FILL);
        Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
        arrowPaint.setTypeface(font);
        arrowPaint.setAntiAlias(true);

        textPaint = new Paint();
        textPaint.setColor(textColor);
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setStrokeWidth(1f);
        textPaint.setAntiAlias(true);

        imagePaint = new Paint();
        imagePaint.setStyle(Paint.Style.FILL);
        imagePaint.setStrokeWidth(1f);
        imagePaint.setAntiAlias(true);
    }

    /**
     * 设置默认选中值
     * @param switchbg
     */
    public void switchLeftOn(SWITCHBG switchbg) {
        this.switchbg = switchbg;
    }

    /**
     * 更新开关状态
     * @param switchbg
     */
    public void updateSwitchState(SWITCHBG switchbg){
        this.switchbg = switchbg;
        invalidate();
    }

    public enum SWITCHBG {
        LEFT, MID, RIGHT
    }

    /**
     * 三个点击事件回调
     */
    public interface SwitchScrollListner {
        void leftListner();

        void midListner();

        void rightListner();
    }

    SwitchScrollListner switchScrollListner;

    public void setSwitchScrollListner(SwitchScrollListner switchScrollListner) {
        this.switchScrollListner = switchScrollListner;
    }
}
在外部调用的时候可以用
SwitchScrollListner 


来进行自定义操作

欢迎各位童鞋提出宝贵意见





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值