该篇文章从eoeAndroid搬迁过来的,原文地址:[Android实例] 两边都能滑动的数据间隔选择SpaceBar
前几天看汽车报价APP,突然发现一个很带感的效果,类似于seekbar,不过能够两边滑动,用处是能够在指定大小数据范围内进行选择你需求的范围,效果图如下,至于主要代码如下:
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
int width = getWidth();
paint.setColor(Color.rgb(0, 197, 48));
canvas.drawRect(20, 70, width - 20, 80, paint);
int spaceWidth = (width - 40) / 10;
for (int i = 0; i < 11; i++) {
paint.reset();
paint.setColor(Color.GRAY);
int maxWidth = i * spaceWidth + 20;
canvas.drawRect(maxWidth, 60, maxWidth + 1, 70, paint);
canvas.drawRect(maxWidth, 80, maxWidth + 1, 90, paint);
if (i < 10) {
for (int j = 1; j < 5; j++) {
int smallWidth = j * spaceWidth / 5 + maxWidth;
canvas.drawRect(smallWidth, 65, smallWidth + 1, 70, paint);
canvas.drawRect(smallWidth, 80, smallWidth + 1, 85, paint);
}
}
paint.setColor(Color.GRAY);
paint.setTextSize(18);
double n = minNum + (double) (maxNum - minNum) / 10 * i;
String num = (new BigDecimal(n + "").setScale(0,
BigDecimal.ROUND_HALF_UP)).intValue() + "";
float numX = maxWidth - paint.measureText(num) / 2;
canvas.drawText(num, numX, 55, paint);
canvas.drawText(num, numX, 110, paint);
}
if (isMinTouch || isMaxTouch) {
paint.reset();
paint.setColor(Color.WHITE);
paint.setTextSize(18);
float touchX = 0;
if (isMinTouch) {
touchX = minTouch;
}
if (isMaxTouch) {
touchX = maxTouch;
}
canvas.drawBitmap(
((BitmapDrawable) getResources().getDrawable(
R.drawable.space_text_bg)).getBitmap(), null,
new Rect((int) touchX, 0, (int) touchX + 40, 40), paint);
double n = minNum
+ (double) (touchX / spaceWidth * (maxNum - minNum) / 10);
String num = (new BigDecimal(n + "").setScale(0,
BigDecimal.ROUND_HALF_UP)).intValue() + "";
float numX = touchX + (40 - paint.measureText(num)) / 2;
canvas.drawText(num, numX, 25, paint);
}
paint.reset();
if (maxTouch == 0) {
maxTouch = width - 40;
}
canvas.drawBitmap(
((BitmapDrawable) getResources().getDrawable(
R.drawable.space_button_bg)).getBitmap(), null,
new Rect((int) minTouch, 120, (int) minTouch + 40, 160), paint);
canvas.drawBitmap(
((BitmapDrawable) getResources().getDrawable(
R.drawable.space_button_bg)).getBitmap(), null,
new Rect((int) maxTouch, 120, (int) maxTouch + 40, 160), paint);
paint.reset();
paint.setColor(Color.GRAY);
canvas.drawRect(20, 70, minTouch + 20, 80, paint);
canvas.drawRect(maxTouch + 20, 70, width - 20, 80, paint);
paint.reset();
double min = minNum
+ (double) (minTouch / spaceWidth * (maxNum - minNum) / 10);
double max = minNum
+ (double) (maxTouch / spaceWidth * (maxNum - minNum) / 10);
onSpaceChangeListener
.onChangeListener((new BigDecimal(min + "").setScale(0,
BigDecimal.ROUND_HALF_UP)).intValue(), (new BigDecimal(
max + "").setScale(0, BigDecimal.ROUND_HALF_UP))
.intValue());
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
if (action == MotionEvent.ACTION_UP) {
isMaxTouch = false;
isMinTouch = false;
startEvent = null;
moveEvent = null;
invalidate();
} else if (action == MotionEvent.ACTION_MOVE) {
if (isMinTouch || isMaxTouch) {
moveEvent = MotionEvent.obtain(event);
float move = moveEvent.getX() - startEvent.getX();
if (isMinTouch) {
if (minTouch + move >= 0 && minTouch + move + 40 < maxTouch) {
minTouch = minTouch + move;
invalidate();
startEvent = MotionEvent.obtain(event);
} else if (minTouch + move + 40 >= maxTouch
&& maxTouch + move + 40 <= getWidth()) {
minTouch = minTouch + move;
maxTouch = maxTouch + move;
invalidate();
startEvent = MotionEvent.obtain(event);
}
} else if (isMaxTouch) {
if (maxTouch + move + 40 <= getWidth()
&& maxTouch + move > minTouch + 40) {
maxTouch = maxTouch + move;
invalidate();
startEvent = MotionEvent.obtain(event);
} else if (maxTouch + move <= minTouch + 40
&& minTouch + move >= 0) {
minTouch = minTouch + move;
maxTouch = maxTouch + move;
invalidate();
startEvent = MotionEvent.obtain(event);
}
}
}
} else if (action == MotionEvent.ACTION_DOWN) {
if (!isMinTouch && !isMaxTouch) {
startEvent = MotionEvent.obtain(event);
if (event.getX() - minTouch > 0 && event.getX() - minTouch < 40) {
isMinTouch = true;
} else if (event.getX() - maxTouch > 0
&& event.getX() - maxTouch < 40) {
isMaxTouch = true;
} else {
return false;
}
} else {
return false;
}
}
return true;
}
用法:
<com.example.spacebar.SpaceBar
android:id="@+id/spacebar1"
android:layout_width="match_parent"
android:layout_height="110dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
app:maxNum="300"
app:minNum="100" />
<com.example.spacebar.SpaceBar
android:id="@+id/spacebar2"
android:layout_width="match_parent"
android:layout_height="110dp" />
下载地址:项目代码