自定义控件,滑动开关

class BallView extends View {
    private Paint paint;
    private Bitmap mSwitchBackground;
    private Bitmap mSwitchButton;
    private int mBackgroundWidth;
    private int mButtonWidth;
    private int downX;
    private int downY;
    private int moveX;
    private int moveY;
    private long downtime;
    private int buttonX;
    private boolean on_off = false;
    private int mBackgroundHeight;
    private int mMaxX;
    private int buttonXhalf;
    private TypedArray mTypedArray;

    public BallView(Context context) {
        this(context,null);

    }
    public BallView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }
    public BallView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        intiview();
        mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.My_view);
    }
    private void intiview() {
        paint = new Paint();//创建画笔
        //bitmap引入滑动按钮背景图
        mSwitchBackground = BitmapFactory.decodeResource(getResources(), R.drawable.switch_backgound);
        //bitmap引入滑动按钮
        mSwitchButton = BitmapFactory.decodeResource(getResources(), R.drawable.switch_button);
        //获取背景图的宽高
        mBackgroundHeight = mSwitchBackground.getHeight();
        mBackgroundWidth = mSwitchBackground.getWidth();
        //获取滑动按钮的宽
        mButtonWidth = mSwitchButton.getWidth();
        //滑动按钮滑动的宽度
        mMaxX = mBackgroundWidth - mButtonWidth;
        //粘性判断值
        buttonXhalf = mMaxX / 2;
        //触摸事件监听
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN://手指按下
                        //获取手指按下的(X,Y)坐标
                        downX=(int)getX();
                        downY=(int)getY();
                        //手指移动的距离坐标为0
                        moveX=0;
                        moveY=0;
                        //获取手指按下的时间
                        downtime=System.currentTimeMillis();
                    break;
                    case MotionEvent.ACTION_MOVE://手指移动
                        //移动的距离等于移动时的坐标和按下时的坐标差,取绝对值
                        moveX+=Math.abs(getX()-downX);
                        moveY+=Math.abs(getY()-downY);
                        //实时更新坐标
                        downX=(int) event.getX();
                        downY=(int)event.getY();
                        //按钮跟着手指实时移动的距离
                        buttonX=(int) getX()+downX;
                        break;
                    case MotionEvent.ACTION_UP://手指抬起
                        //获取手指抬起的时间
                        long movetime=System.currentTimeMillis()-mBackgroundWidth;
                    //判断点击与滑动事件,手指按下与抬起的时间过短并且移动的距离过小判断为点击事件,否为触摸事件
                        if (movetime>200&&(moveX>20||moveY>20)){
                            //此处判断为滑动事件,不做操作,break之后调用flushviewbound();方法
                        }else {
                            //判断为点击事件,状态判断,滑动按钮移动
                            if (on_off){
                                on_off=false;
                                buttonX=0;
                            }else{
                                on_off=true;
                                buttonX=mMaxX;
                            }
                            invalidate();
                        }
                        //粘性判断
                        if (buttonX>0&&buttonX<mMaxX){
                            //是否中间坐标判断,改变状态值
                            if (buttonX<buttonXhalf){
                                on_off=false;
                                buttonX=0;
                            }else {
                                on_off=true;
                                buttonX=mMaxX;
                            }
                        }
                        break;
                }
                //调用此方法
                flushviewbound();
                //消费此次触摸事件
                return true;
            }
        });
    }

    private void flushviewbound() {
        //滑动越界判断
        if (buttonX<0){
            //最小滑到坐标为零
            buttonX=0;
        }else if (buttonX>mMaxX){
            //最大坐标宽度
            buttonX=mMaxX;
        }
        //接口回调
        if (mOnNumberChangerListener !=null){
            mOnNumberChangerListener.OnNumberChanger(!on_off);
        }
        //调用ondraw();
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        /*
        * 背景的寬高
        * */
        setMeasuredDimension(mBackgroundWidth,mBackgroundHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画笔颜色
        paint.setColor(Color.RED);
        //消除锯齿
        paint.setAntiAlias(true);
        //画布背景,滑动按钮背景图
        canvas.drawBitmap(mSwitchBackground,0,0,paint);
        //添加按钮图片
        canvas.drawBitmap(mSwitchButton,buttonX,0,paint);
    }
    //接口回调
    public interface OnNumberChangerListener{
        void OnNumberChanger(boolean value);
    }

    //定义接口对象
    private OnNumberChangerListener mOnNumberChangerListener;

    //设置方法接收外界传来的接口对象方法
    public void setOnNumberChangerListener(OnNumberChangerListener onNumberChangerListener){
        mOnNumberChangerListener =onNumberChangerListener;
    }
}
MainLayout界面
 
 
mContainer = (RelativeLayout) findViewById(R.id.relativeLayout);

mBallView = new BallView(this);

mContainer.addView(mBallView);

mBallView.setOnNumberChangerListener(new BallView.OnNumberChangerListener() {
    @Override
    public void OnNumberChanger(boolean value) {
        Toast.makeText(BallActivity.this,""+value,Toast.LENGTH_SHORT).show();
    }
});

layout布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/relativeLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="ResAuto">

    <com.example.admin.ballveiwdemo.BallView
        android:id="@+id/ball"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

猜你喜欢

转载自blog.csdn.net/CC96864/article/details/80338077