Android自绘控件之-开关按钮的简单实现

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class MyView extends View {

    private Paint paint;
    private Bitmap bg;
    private Bitmap show;
    //记录起始X坐标
    private int firstX = 0;
    //记录移动中的X坐标
    private int moveX;
    //记录最终绘制时的X坐标
    private int lastX;
    //记录手指点击坐标
    private int onTouchDownX,onTouchDownY;
    //记录手指松开坐标
    private int onTouchUpX,onTouchUpY;
    //记录开关状态
    boolean isOpen = false;

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

    public MyView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void initView() {
        paint = new Paint();
        bg = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
        show = BitmapFactory.decodeResource(getResources(), R.drawable.show);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(bg.getWidth(),bg.getHeight());
    }

    @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);
        canvas.drawBitmap(bg,0,0,paint);
        String mes = Integer.toString(lastX);
        //Log.i("---------",mes);
        canvas.drawBitmap(show,lastX,0,paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //获取点击时的坐标
                onTouchDownX = (int)event.getX();
                onTouchDownY = (int)event.getY();
                break;
            case MotionEvent.ACTION_MOVE:

//                if (isOpen){
//                    Log.i("-----","移动开始_开");
//                }else {
//                    Log.i("-----","移动开始_关");
//                }

                //获取移动坐标
                moveX = (int)event.getX();

                /**
                 * 判断手指所在X轴是否超过按钮的一半,
                 * 没有超过一半的时候,按钮不动
                 * 超过一半但按钮右边缘没有达到控件右边缘,按钮跟随手指移动
                 * 当按钮右边缘达到控件右边缘时,按钮不动
                 */
                if (moveX<show.getWidth()/2){
                    lastX=0;
                    isOpen = false;
                }else if (moveX>bg.getWidth()-show.getWidth()/2){
                    lastX = bg.getWidth()-show.getWidth();
                    isOpen = true;
                }else {
                    lastX = moveX-show.getWidth()/2;
                }

//                if (isOpen){
//                    Log.i("-----","移动结束_开");
//                }else {
//                    Log.i("-----","移动结束_关");
//                }

                break;
            case MotionEvent.ACTION_UP:
                
                //手指抬起时的坐标
                onTouchUpX = (int)event.getX();
                onTouchUpY = (int)event.getY();

//                if (isOpen){
//                    Log.i("-----","抬起开始_开");
//                }else {
//                    Log.i("-----","抬起开始_关");
//                }

                //当手指按下时坐标和手指抬起时坐标的绝对值相差超过5的时候,判断为滑动状态
                if (Math.abs(onTouchDownX-onTouchUpX)>5||Math.abs(onTouchDownY-onTouchUpY)>5){

//                    if (isOpen){
//                        Log.i("-----","滑动开始_开");
//                    }else {
//                        Log.i("-----","滑动开始_关");
//                    }

                    //判断按钮是否移动了
                    if (!(moveX<show.getWidth()/2&&moveX>bg.getWidth()-show.getWidth()/2)){
                        //只要按钮移动,那么此时的moveX的值就是按钮的中心,判断这个中心的位置是否超过控件的中心值,确定手指抬起后按钮的状态
                        if(moveX<bg.getWidth()/2){
                        lastX = 0;
                        isOpen = false;
                        }else {
                            lastX = bg.getWidth()-show.getWidth();
                            isOpen = true;
                        }
                    }

//                    if (isOpen){
//                        Log.i("-----","滑动结束_开");
//                    }else {
//                        Log.i("-----","滑动结束_关");
//                    }

                }else {
//                    if (isOpen){
//                        Log.i("-----","点击开始_开");
//                    }else {
//                        Log.i("-----","点击开始_关");
//                    }
                    
                    //按钮没有移动,此时不管点击那里,都取反值,来响应用户操作
                    if (isOpen){
                        lastX = 0;
                    }else {

                        lastX = bg.getWidth() - show.getWidth();
                    }
                    isOpen=!isOpen;
                }

//                if (isOpen){
//                    Log.i("-----","抬起结束_开");
//                }else {
//                    Log.i("-----","抬起结束_关");
//                }

                break;
        }

        setUp();
        return true;
    }

    private void setUp() {

//        if (!(moveX<show.getWidth()/2&&moveX>bg.getWidth()-show.getWidth()/2)){
//            if(moveX<bg.getWidth()/2){
//                lastX = 0;
//            }else {
//                lastX = bg.getWidth()-show.getWidth();
//            }
//        }
        invalidate();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_19681347/article/details/80285757
今日推荐