自定义开关

滑动按钮
背景图效果
要求:1.可以点击响应开关
2.手指可以滑动开关,放手后回弹到贴近的一侧

/**
 * Created by huanmeiqi on 2016/08/19.
 * Describe 自定义开关
 * 步骤
 * 1.重构3个构造方法
 * 2.定义initView(),完成加载BitMap、设置画笔等操作
 * 3.重写OnMearsue,用setMeasuredDimension方法设置View的宽高
 * 4.重写OnDraw(),完成绘制
 * 5.重写OnTouchEvent()完成滑动回调
 * 6.设置点击事件监听
 * 7.解决点击与滑动的冲突
 */
public class SwitchView extends View implements View.OnClickListener{
    private Context context;
    private Bitmap back_bitmap;
    private Bitmap button_bitmap;
    private Paint paint;
    private int back_width;
    private int button_width;
    private int height;
    /*
    滑动按钮左边相对View的距离
     */
    private float alignLeft;
    /*
    滑动按钮左边相对View的最大距离
     */
    private int alignLeftMax;
    private float startX;
    private float endX;
    private float moveX;
    /*
    默认switch为打开状态
     */
    private boolean isSwitchOpen = true;
    /*
    默认switch可以点击
     */
    private boolean isEnClick = true;

    /*
    重构三个构造方法
     */
    public SwitchView(Context context) {
        this(context,null);
    }

    public SwitchView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public SwitchView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        initView();
    }
    /*
    初始化操作
     */
    private void initView() {
        //获取开关背景图片
        back_bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.switch_background);
        //获取滑动按钮图片
        button_bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button);
        //获取图片的宽高,两张图的高度一致
        back_width = back_bitmap.getWidth();
        button_width = button_bitmap.getWidth();
        height = button_bitmap.getHeight();
        //滑动按钮左边相对View的最大距离
        alignLeftMax = back_width - button_width;
        alignLeft = alignLeftMax;
        //创建并设置画笔
        paint = new Paint();
        paint.setAntiAlias(true);//抗锯齿
        //设置点击事件的监听
        setOnClickListener(this);
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch(event.getAction()){
                    case MotionEvent.ACTION_DOWN : //手指按下
                        //记下初始按下位置
                        startX = event.getX();

                        break;
                    case MotionEvent.ACTION_MOVE : //手指滑动
                        //再次记下滑动过程的位置
                        endX = event.getX();
                        //计算滑动的距离
                        moveX = endX - startX;

                        alignLeft += moveX;//更新左边的相对距离

                        startX = endX;//实时更新起始坐标
                        //屏蔽非法值
                        if(alignLeft < 0){
                            alignLeft = 0;
                        }else if(alignLeft > alignLeftMax){
                            alignLeft = alignLeftMax;
                        }

                        //更新
                        invalidate();//调用它,会重新执行OnDraw()
                        break;
                    case MotionEvent.ACTION_UP : //手指抬起,需要它回弹到“开”或者“关”的状态。还要在这里解决事件冲突

                        if(Math.abs(moveX) > 0){//有滑动的情况,修改不能点击

                            isEnClick = false;
                            if(Math.abs(alignLeft) < alignLeftMax/2){
                                alignLeft = 0;
                            }else if(Math.abs(alignLeft) > alignLeft/2){
                                alignLeft = alignLeftMax;
                            }else if(Math.abs(alignLeft) == alignLeftMax/2){
                                alignLeft = 0;
                            }
                            invalidate();
                        }else{
                            isEnClick = true;//否则,修改为可以点击
                        }

                        break;
                }

                return true;
            }
        });

    }
    /*
    设置View的宽高
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //View的宽高就是背景图片的宽高
        setMeasuredDimension(back_width,height);
    }
    /*
    绘制View
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(back_bitmap,0,0,paint);//背景图左顶点与View的左顶点重合
        canvas.drawBitmap(button_bitmap,alignLeft,0,paint);//滑动按钮相对View左边距离是不断变动的
    }





    /*
     设置点击事件的监听
     */
    @Override
    public void onClick(View v) {
        if(isEnClick){
            if(isSwitchOpen){
                alignLeft = 0;
            }else{
                alignLeft = alignLeftMax;
            }
            isSwitchOpen = !isSwitchOpen;//改变状态
            invalidate();//重绘
        }

    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值