Android 自定义View学习(3)--仿IOS风格滑动按钮

谢谢收看自定义学习的第三期,放假前我曾畅想七天每天都更新,结果。。。


大家知道Android其实也自带滑动按钮叫Switch


上图中的WLAN,蓝牙就是典型的switch,但是这个按钮只支持4.0以上的手机。。所以有时候我们还是要自定义一个滑动按钮,而ios风格的滑动按钮比较好看,废话不说上代码。


/**
	 * 画笔
	 */
	private Paint mPaint;

	/**
	 * 按钮
	 */
	private Bitmap bitNormal;

	/**
	 * 框架
	 */
	private Bitmap bitFram;

	/**
	 * 底部的图片
	 */
	private Bitmap bitBottom;

	/**
	 * 背景的黑色图片
	 */
	private Bitmap bitMask;

	/**
	 * 实现俩图相交取上层
	 */
	private PorterDuffXfermode mXfermode;
	/**
	 * 面积
	 */
	private RectF mRectF;

	/**
	 * button按钮位置
	 */
	private float mBtnPos;
	/**
	 * 状态为on时候位置
	 */
	private float mBtnOn;
	/**
	 * 状态为off时候位置
	 */
	private float mBtnOff;

	/** 首次按下的X */
	private float mFirstDownX;
	/** 默认为开启 */
	private boolean isCheck = true;

	private int mClickTimeout;

	private int time;
<pre name="code" class="java"> 下面我们按部就班重写构造方法。。

 

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

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

	public ViewButton(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init();
	}

	private void init() {
		mPaint = new Paint();
		mPaint.setColor(Color.WHITE);
		mClickTimeout = ViewConfiguration.getPressedStateDuration()
				+ ViewConfiguration.getTapTimeout();
		bitNormal = BitmapFactory.decodeResource(getResources(),
				R.drawable.checkswitch_btn_unpressed);
		bitFram = BitmapFactory.decodeResource(getResources(),
				R.drawable.checkswitch_frame);
		bitBottom = BitmapFactory.decodeResource(getResources(),
				R.drawable.checkswitch_bottom);
		bitMask = BitmapFactory.decodeResource(getResources(),
				R.drawable.checkswitch_mask);

		// off时距离为0
		mBtnOff = 0;
		// on的时候距离
		mBtnOn = bitFram.getWidth() - bitNormal.getWidth();
		//判断初始距离
		mBtnPos = isCheck ? mBtnOn : mBtnOff;
		mRectF = new RectF(0, 0, bitMask.getWidth(), bitMask.getHeight());
        //图层相交时显示上层
		mXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
	}
只是初始了一些变量

@Override
	protected void onDraw(Canvas canvas) {
		canvas.saveLayerAlpha(mRectF, 225, 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(bitMask, 0, 0, mPaint);
		mPaint.setXfermode(mXfermode);
		// 绘制底部图片
		canvas.drawBitmap(bitBottom, mBtnPos, 0, mPaint);
		mPaint.setXfermode(null);
		canvas.drawBitmap(bitNormal, mBtnPos, 0, mPaint);

		canvas.restore();
	}

重写onDraw把图像画出来


public boolean onTouchEvent(MotionEvent event) {
		float x = event.getX();
		float y = event.getY();
		int distance = (int) (event.getX() - mFirstDownX);
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			mFirstDownX = x;
			break;
		case MotionEvent.ACTION_MOVE:

			mBtnPos = (isCheck ? mBtnOn : mBtnOff) + distance;
			// 如果为on的时候还往左滑动
			if (isCheck && distance < 0) {
				mBtnPos = mBtnOn;
				return true;
			}
			// 如果为off的时候还往左滑动
			if (!isCheck && distance > 0) {
				mBtnPos = mBtnOff;
				return true;
			}
			//限制了最大距离
			if (distance > Math.abs(mBtnOn)) {
				mBtnPos = mBtnOff;
			}
			if (distance < mBtnOn) {
				mBtnPos = mBtnOn;
			}
			break;
		case MotionEvent.ACTION_UP:
			
			if (Math.abs(distance) >= Math.abs(mBtnOn)) {
				isCheck = !isCheck;
			}
			//点击事件
			time = (int) (event.getEventTime() - event.getDownTime());
			if (time < mClickTimeout) {
				isCheck = !isCheck;
				mBtnPos = isCheck ? mBtnOn : mBtnOff;

			}
			if (mBtnPos >= mBtnOn / 2) {
				mBtnPos = mBtnOff;

			}
			if (mBtnPos < mBtnOn / 2) {
				mBtnPos = mBtnOn;

			}
			break;
		default:
			break;
		}
		invalidate();
		return true;
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int width = bitMask.getWidth();
		int height = bitMask.getHeight();
		setMeasuredDimension(width, height);
	}

	public void setCheck(boolean isCheck) {
		this.isCheck = isCheck;
		invalidate();
	}

上面就是一些事件的判断。。

自己的状态不太好啊。。去买脉动了


项目源码



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值