android 自定义竖开关按钮 SwitchButton

    最近参照网上的一些资料写了一个竖直的 SwitchButton,记录如下:


package com.example.switchbutton;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;


public class VerticalSwitchButton extends View {

private final int MAX_ALPHA = 255;       // alpha value
private Bitmap mSwitchBottom, mSwitchThumb;
    private float mCurrentY = 0;
    private boolean mSwitchOn = false;       //default off
    private int mMoveLength = 0;             //the max movable length
    private float mLastY = 0;                //the first down Y position
    private Rect mDest = null;               //target draw area 
    private int mDeltY = 0;                  //the offset of moving
    private Paint mPaint = null;
    private OnChangeListener mListener = null;
    private boolean mFlag = false;
    private int destWidth = 0;               //target draw area width
    private int destHeight = 0;              //target draw area height
    private boolean mIsScrolled = false;     //whether is scrolling


    public VerticalSwitchButton(Context context) {
        this(context, null);
        // TODO Auto-generated constructor stub
    }


    public VerticalSwitchButton(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        // TODO Auto-generated constructor stub
    }


    public VerticalSwitchButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
        init();
    }  


    /**
     * Initialize the sources
     */
    public void init() {
        mSwitchBottom = BitmapFactory.decodeResource(getResources(),
                R.drawable.switch_bottom);
        mSwitchThumb = BitmapFactory.decodeResource(getResources(),
                R.drawable.switch_btn_pressed);


        destWidth = mSwitchThumb.getWidth() + 1;
        destHeight = mSwitchBottom.getHeight() + 1;
        mMoveLength = mSwitchBottom.getHeight() - mSwitchThumb.getHeight();
        mDest = new Rect(0, 0, destWidth, destHeight);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setAlpha(MAX_ALPHA);
        
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); 
    }


    @Override  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        setMeasuredDimension(mSwitchThumb.getWidth(), mSwitchBottom.getHeight());
    }


    @Override  
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub  
        super.onDraw(canvas);
        
        float thumbY = 0;
        
        if (mDeltY > 0 || mDeltY == 0 && mSwitchOn) {
        thumbY = destHeight - (mSwitchThumb.getHeight());
        } else if (mDeltY < 0 || mDeltY == 0 && !mSwitchOn) {
        thumbY = 0;
        }


        canvas.saveLayerAlpha(new RectF(mDest), MAX_ALPHA, Canvas.MATRIX_SAVE_FLAG
                | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
                | Canvas.FULL_COLOR_LAYER_SAVE_FLAG
                | Canvas.CLIP_TO_LAYER_SAVE_FLAG);


        canvas.drawBitmap(mSwitchBottom, ((destWidth / 2) - (mSwitchBottom.getWidth() / 2)), 0, null);
        //canvas.drawBitmap(mSwitchThumb, ((destWidth / 2) - (mSwitchThumb.getWidth() / 2)), (destHeight - (mSwitchThumb.getHeight())), null);
        canvas.drawBitmap(mSwitchThumb, ((destWidth / 2) - (mSwitchThumb.getWidth() / 2)), thumbY, null);
        canvas.restore();
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        switch (event.getAction()) {
        
       case MotionEvent.ACTION_DOWN:
        mLastY = event.getY();
           return true;
           
       case MotionEvent.ACTION_MOVE:
        mCurrentY = event.getY();
           mDeltY = (int) (mCurrentY - mLastY);
           
           //To assess the click event
           if (mDeltY > 10 || mDeltY < -10) {
            mIsScrolled = true;
           }
           
           /*
            * No need to do anything, When switch on and deltY > 0,
            * or switch off and deltY < 0.
            */
           if ((mSwitchOn && mDeltY > 0) || (!mSwitchOn && mDeltY < 0)) {
               mFlag = true;
               mDeltY = 0;
           }
           
           if (Math.abs(mDeltY) > mMoveLength) {
               mDeltY = mDeltY > 0 ? mMoveLength : - mMoveLength;
           }
           invalidate();
           break;
           
       case MotionEvent.ACTION_UP:
       
        //Is a click event.
        if (!mIsScrolled) {
        mDeltY = mSwitchOn ? -mMoveLength : mMoveLength;
        mSwitchOn = !mSwitchOn;
        if (mListener != null) {
        mListener.onChange(this, mSwitchOn);
        }
        invalidate();
        mDeltY = 0;
        break;
        }
        mIsScrolled = false;
       
        if (Math.abs(mDeltY) > 0 && Math.abs(mDeltY) < mMoveLength / 2) {
        mDeltY = 0;
        invalidate();
        return true;
        } else if (Math.abs(mDeltY) > mMoveLength / 2) {
        mDeltY = mDeltY > 0 ? mMoveLength : -mMoveLength;
        mSwitchOn = !mSwitchOn;
        if(mListener != null) {
                   mListener.onChange(this, mSwitchOn);
               }
               invalidate();
               mDeltY = 0;
               return true;
        } else if (mDeltY == 0 && mFlag) {
        mDeltY = 0;
        mFlag = false;
        return true;
        }
           return super.onTouchEvent(event);
       default:
           break;
   }
   invalidate();
        return super.onTouchEvent(event);
    }
      
    public void setOnChangeListener(OnChangeListener listener) {
        mListener = listener;
    }


    public interface OnChangeListener {
        public void onChange(VerticalSwitchButton sb, boolean state);
    }
    
    public void toggle() {
    setChecked(!mSwitchOn);
    }
    
    public void setChecked(boolean checked) {
    mSwitchOn = checked;
    if(mListener != null) {
            mListener.onChange(this, mSwitchOn);
        }
    invalidate();
    } 
}  


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值