android ——滑动开关

一 :效果图

  开启时:

关闭时:

二:步骤:

1. 写一个类SlippingBtn继承View,并实现OnTouchListener接口。重写父类两个构造函数(一个参数的,二个参数的)

2. 初始化滑块的背景图片并记录滑动块处于开启和关闭时的位置,注册setOnTouchListener事件

开启时:

  滑动块左边坐标:bg_on的宽度减去bg_slipping的宽度
   滑动块上面坐标:0
   滑动块右面坐标:bg_on的宽度
   滑动块下面坐标:bg_slipping的高度
关闭时:
   滑动块左边坐标:0
   滑动块上面坐标:0
   滑动块右面坐标:获取滑块的宽度
   滑动块下面坐标:bg_on的高度
3、初始化开关的状态 setToggleState(boolean status),并用一个成员变量currToggleState记住当前开关是否开启
4、设置监听器,监听滑动开关状态的变化,响应不同的事件
5、触摸时的逻辑:

    case MotionEvent.ACTION_DOWN:

         记住当前的位置;滑块处于滑行的状态;

          break;

     case MotionEvent.ACTION_MOVE:

           更新滑块的位置;

           break;

     case MotionEvent.ACTION_UP:

          滑块静止;

           判断滑块的位置和bg_on的长度比较:记录开关状态

           记录前一次的状态,判断是否这只监听器,及执行监听器的方法,

           将前一次的状态记录为当前的状态;

           break;

      invalidate()刷新界面; 

6、onMeasure():测量bg_on的长和宽

7、绘制开关开启和关闭以及滑块的背景

具体代码如下:

public class SlippingBtn extends View implements OnTouchListener{
    
    private Bitmap bg_on,bg_off,bg_slipping;
    private Rect bg_on_location,bg_off_location;
    private float slppCurLocation;//滑块当钱的位置
    private boolean isSlipping;//滑块是否在滑动
    private boolean currToggleState;//设置开关当前的状态
    private boolean isToggleStatusListener; //是否开启开关的状态监听
    private boolean proToggleState;//上一次开关的状态,默认为false;
    private OnToggleStatusListener listener;//开关监听器

    
    public HuaDong(Context context) {
        super(context);
        initView();
    }
    
    public HuaDong(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }
    
    private void initView(){
        bg_on = BitmapFactory.decodeResource(getResources(), R.drawable.on_btn);
        bg_off = BitmapFactory.decodeResource(getResources(), R.drawable.off_btn);
        bg_slipping = BitmapFactory.decodeResource(getResources(), R.drawable.white_btn);
        
        //开关打开时滑块的坐标
        bg_on_location = new Rect(bg_on.getWidth()-bg_slipping.getWidth(),
                0, bg_on.getWidth(), bg_on.getHeight());
        //开关关闭时滑块的坐标
        bg_off_location = new Rect(0, 0, bg_slipping.getWidth(), 
                bg_slipping.getHeight());
        setOnTouchListener(this);
        
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            slppCurLocation = event.getX();
            isSlipping = true;
            break;
        case MotionEvent.ACTION_MOVE:
            slppCurLocation = event.getX();
            break;
        case MotionEvent.ACTION_UP:
            isSlipping = false;
            if(slppCurLocation < bg_on.getWidth()/2){
                currToggleState = false;
            }else{
                currToggleState = true;
            }
            
            if(isToggleStatusListener && currToggleState != proToggleState){
                proToggleState = currToggleState;//前一个状态这只为现在的状态;
                listener.onToggleStatus(currToggleState);
            }
            break;
        default:
            break;
        }
        invalidate();
        return true;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(bg_on.getWidth(),bg_on.getHeight() );
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Matrix matrix = new Matrix();
        Paint paint = new Paint();
        if(currToggleState){//开启开关
            canvas.drawBitmap(bg_on, matrix, paint);
        }else{//关闭开关
            canvas.drawBitmap(bg_off, matrix, paint);
        }
        //h绘制滑块
        float left_slipp = 0;//滑块的位置
        if(isSlipping){//滑动的状态下
            left_slipp = slppCurLocation - bg_slipping.getWidth()/2;
        }else{//滑块静止
            if(currToggleState){
                left_slipp = bg_on.getWidth() - bg_slipping.getWidth();
            }else{
                left_slipp = 0;
            }
        }
        
        if(left_slipp < 0){
            left_slipp = 0;
        }else if(left_slipp >(bg_on.getWidth()-bg_slipping.getWidth())){
            left_slipp = bg_on.getWidth() - bg_slipping.getWidth();
        }
        
        canvas.drawBitmap(bg_slipping, left_slipp,0, paint);
    }
    
    //设置d当前开关的状态
    public void setToggleState(boolean toggleStatus){
        currToggleState = toggleStatus;
    }
        
    public interface OnToggleStatusListener{
        /**
         * 开关状态变化时执行
         * @param toggeState 变化后的开关状态
         */
        void onToggleStatus(boolean toggeState);
    }
    //监听滑块的状态
    public void setOnToggleStatusListener(OnToggleStatusListener listener){
        this.listener = listener;
        isToggleStatusListener  = true;
    }

}

xml文件

    <com.view.util.SlippingBtn
        android:id="@+id/hd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

Activity调用:

    SlippingBtn toggle = (SlippingBtn) findViewById(R.id.hd);
        toggle.setToggleState(true);
        toggle.setOnToggleStatusListener(new OnToggleStatusListener() {
            
            @Override
            public void onToggleStatus(boolean toggeState) {
                if(toggeState){
                    Toast.makeText(getApplicationContext(), "开启开关", 1).show();
                }else{
                    Toast.makeText(getApplicationContext(), "关闭开关", 1).show();
                }
                
            }
        });

 

   

原文地址:https://www.cnblogs.com/wei1228565493/p/4536511.html