您的位置:首页 > 移动开发 > Android开发

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

2014-10-07 16:42 671 查看
谢谢收看自定义学习的第三期,放假前我曾畅想七天每天都更新,结果。。。



大家知道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_S***E_FLAG
				| Canvas.CLIP_S***E_FLAG | Canvas.HAS_ALPHA_LAYER_S***E_FLAG
				| Canvas.FULL_COLOR_LAYER_S***E_FLAG
				| Canvas.CLIP_TO_LAYER_S***E_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();
	}



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

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

项目源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐