双拖动条自定义seekbar(带浮动textView)

转载请注明出处:http://blog.csdn.net/sctu_vroy/article/details/47456629

多说无益,先上效果图:

自定义seekbar,继承ImageView,双拖动条(带浮动textview),不会与其他滑动事件冲突,可用于类似侧滑菜单的布局中。文章末尾附上源码下载链接(内含双拖动条seekbar以及单拖动条seekbar,免积分下载),欢迎各位大牛纠bug!

实现思路:

1)继承于ImageView

2)构造函数设置最值

3)重写onMeasure()方法获取尺寸

4)重写onTouchEvent(),监听ACTION_DOWN, ACTION_MOVE, ACTION_UP

5)重写onDraw()绘制整个自定义seekbar

篇幅有限,这里只介绍onDraw()的实现,其他有兴趣请下载源码研读,谢谢。

样式的修改基本都在onDraw()方法中,唯一要另外注意的是,对于不同尺寸手机,需要修改onMeasure()里的常数来调整控件大小,此demo只做了5寸屏的适配。

onDraw()方法:

protected synchronized void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		Bitmap l_bg = BitmapFactory.decodeResource(getResources(), R.drawable.red_seekbar);
		Bitmap m_bg = BitmapFactory.decodeResource(getResources(), R.drawable.yellow_seekbar);
		Bitmap r_bg = BitmapFactory.decodeResource(getResources(), R.drawable.green_seekbar);
		Bitmap m_progress = BitmapFactory.decodeResource(getResources(), R.drawable.yellow_seekbar);

		canvas.drawBitmap(l_bg, padding - thumbHalfWidth, 0.5f * (getHeight() - l_bg.getHeight()), paint);

		float bg_middle_left = padding - thumbHalfWidth + l_bg.getWidth();// 获取初始状态下中间部分的左边界坐标
		float bg_middle_right = getWidth() - padding + thumbHalfWidth - l_bg.getWidth();// 获取初始状态下中间部分的右边界坐标
		
		float m_scale = (bg_middle_right - bg_middle_left) / m_progress.getWidth();// 获得中间部分变化比例
		Matrix m_mx = new Matrix();
		m_mx.postScale(m_scale, 1f);
		Bitmap m_bg_new = Bitmap.createBitmap(m_bg, 0, 0, m_progress.getWidth(), m_progress.getHeight(), m_mx, true);
		canvas.drawBitmap(m_bg_new, bg_middle_left, 0.5f * (getHeight() - m_bg.getHeight()), paint);

		canvas.drawBitmap(r_bg, bg_middle_right, 0.5f * (getHeight() - r_bg.getHeight()), paint);

		float rangeL = normalizedToScreen(normalizedMinValue);
		float rangeR = normalizedToScreen(normalizedMaxValue);
		// float length = rangeR - rangeL;
		float left_scale = rangeL / l_bg.getWidth(); //左边缩放比例
		float pro_scale = (rangeR - rangeL) / m_progress.getWidth(); //中间缩放比例
		float right_scale = (getWidth() - rangeR) /  r_bg.getWidth(); //右边缩放比例
		if(left_scale > 0) {
			Matrix left_mx = new Matrix();
			left_mx.postScale(left_scale, 1f);
			
			Bitmap l_bg_new = Bitmap.createBitmap(l_bg, 0, 0, l_bg.getWidth(), l_bg.getHeight(), left_mx, true);
			canvas.drawBitmap(l_bg_new, padding - thumbHalfWidth, 0.5f * (getHeight() - l_bg.getHeight()), paint);
		}
		if (pro_scale > 0) {

			Matrix pro_mx = new Matrix();
			pro_mx.postScale(pro_scale, 1f);
			try {

				Bitmap m_progress_new = Bitmap.createBitmap(m_progress, 0, 0, m_progress.getWidth(),
						m_progress.getHeight(), pro_mx, true);

				canvas.drawBitmap(m_progress_new, rangeL, 0.5f * (getHeight() - m_progress.getHeight()), paint);
			} catch (Exception e) {
				Log.e(TAG,
						"IllegalArgumentException--width=" + m_progress.getWidth() + "Height=" + m_progress.getHeight()
								+ "pro_scale=" + pro_scale, e);

			}

		}
		if(right_scale > 0) {
			Matrix right_mx = new Matrix();
			right_mx.postScale(right_scale, 1f);
			
			Bitmap r_bg_new = Bitmap.createBitmap(r_bg, 0, 0, r_bg.getWidth(), r_bg.getHeight(), right_mx, true);
			canvas.drawBitmap(r_bg_new, rangeR, 0.5f * (getHeight() - r_bg.getHeight()), paint);
		}

		//绘画左右两个游标
		drawThumbMinValue(normalizedToScreen(normalizedMinValue), getSelectedMinValue() + "dB", canvas);

		drawThumbMaxValue(normalizedToScreen(normalizedMaxValue), getSelectedMaxValue() + "dB", canvas);

		drawThumb(normalizedToScreen(normalizedMinValue), Thumb.MIN.equals(pressedThumb), canvas);

		drawThumb(normalizedToScreen(normalizedMaxValue), Thumb.MAX.equals(pressedThumb), canvas);
}
首先,需要初始化左中右三部分的位置以及长度,绘制出来;拖动后,获取rangeL和rangeR,计算得到三部分的缩放比例,重新绘制;最后,需要绘制左右两个游标,调用方法drawThumbMinValue()和drawThumbMaxValue(),下面介绍:

/**
	 * 绘制左游标
	 * 
	 * @param screenCoord
	 * @param text
	 * @param canvas
	 */
	private void drawThumbMinValue(float screenCoord, String text, Canvas canvas) {

		// 右游标的起始点
		float maxThumbleft = normalizedToScreen(normalizedMaxValue) - thumbHalfWidth;

		// 游标文字区域的右边界位置
		float textRight = screenCoord - thumbHalfWidth + getFontlength(thumbValuePaint, text);

		if (textRight >= maxThumbleft) {
			// 左游标与右游标重叠
			if (pressedThumb == Thumb.MIN) {
				canvas.drawBitmap(tvImage, maxThumbleft - getFontlength(thumbValuePaint, text) - 8,
						(float) ((0.15f * getHeight()) - thumbHalfHeight) - 3, thumbValuePaint);
				canvas.drawText(text, maxThumbleft - getFontlength(thumbValuePaint, text) - 2,
						(float) ((0.4f * getHeight()) - thumbHalfHeight) - 3, thumbValuePaint);
				
			} else {
				canvas.drawBitmap(tvImage, textRight - getFontlength(thumbValuePaint, text) - 8,
						(float) ((0.15f * getHeight()) - thumbHalfHeight) - 3, thumbValuePaint);
				canvas.drawText(text, textRight - getFontlength(thumbValuePaint, text) - 2,
						(float) ((0.4f * getHeight()) - thumbHalfHeight) - 3, thumbValuePaint);
			}

		} else {
			// 正常情况
			canvas.drawBitmap(tvImage, screenCoord - thumbHalfWidth - 8,
					(float) ((0.15f * getHeight()) - thumbHalfHeight) - 3, thumbValuePaint);
			canvas.drawText(text, screenCoord - thumbHalfWidth - 2, (float) ((0.4f * getHeight()) - thumbHalfHeight) - 3,
					thumbValuePaint);

		}

	}

	/**
	 * 绘制右游标
	 * 
	 * @param screenCoord
	 * @param text
	 * @param canvas
	 */
	private void drawThumbMaxValue(float screenCoord, String text, Canvas canvas) {

		// 左游标的右边界
		float minThumbValueRight = normalizedToScreen(normalizedMinValue) - thumbHalfWidth
				+ getFontlength(thumbValuePaint, " " + getSelectedMinValue());

		// 游标文字区域的右边界位置
		float textRight = screenCoord - thumbHalfWidth + getFontlength(thumbValuePaint, text);

		if (textRight >= getWidth()) {
			// 右边界超出or等于seekbar宽度
			canvas.drawBitmap(tvImage, getWidth() - getFontlength(thumbValuePaint, text) - 8,
					(float) ((0.15f * getHeight()) - thumbHalfHeight) - 3, thumbValuePaint);
			canvas.drawText(text, getWidth() - getFontlength(thumbValuePaint, text) - 1,
					(float) ((0.4f * getHeight()) - thumbHalfHeight) - 3, thumbValuePaint);

		} else if ((screenCoord - thumbHalfWidth) <= minThumbValueRight) {
			// 左右游标重叠
			if (pressedThumb == Thumb.MAX) {

				canvas.drawBitmap(tvImage, minThumbValueRight - 8, (float) ((0.15f * getHeight()) - thumbHalfHeight) - 3,
						thumbValuePaint);
				canvas.drawText(text, minThumbValueRight - 1, (float) ((0.4f * getHeight()) - thumbHalfHeight) - 3,
						thumbValuePaint);

			} else  {
				canvas.drawBitmap(tvImage, screenCoord - thumbHalfWidth - 8,
						(float) ((0.15f * getHeight()) - thumbHalfHeight) - 3, thumbValuePaint);
				canvas.drawText(text, screenCoord - thumbHalfWidth - 1,
						(float) ((0.4f * getHeight()) - thumbHalfHeight) - 3, thumbValuePaint);

			}

		} else {
			//正常情况
			canvas.drawBitmap(tvImage, screenCoord - thumbHalfWidth - 8,
					(float) ((0.15f * getHeight()) - thumbHalfHeight) - 3, thumbValuePaint);
			canvas.drawText(text, screenCoord - thumbHalfWidth - 1, (float) ((0.4f * getHeight()) - thumbHalfHeight) - 3,
					thumbValuePaint);
		}

	}
此处需要注意的是要分情况分析:1)正常情况(左游标右边界小于右游标左边界,且二者均不越界);2)游标超越seekbar边界;3)左右游标重叠。。。另外,里面的常数需要根据尺寸进行调整。


源码下载

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值