这是实现的几个seekbar的效果图,大家可以先看看:
第一个seekbar是以提供的bitmap为背景,然后进度条是透明的效果
<SeekBar
android:id="@+id/horiSeekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:progressDrawable="@drawable/seekbar_progress_example"/>
对应的图片drawable xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/background">
<bitmap android:src="@drawable/seekbarbackground"/>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="@color/transparent" />
</shape>
</clip>
</item>
</layer-list>
第二个seekbar是以自己的shape为背景的,有进度条效果,同时添加一个thumb拖动条
<SeekBar
android:id="@+id/horiSeekBar02"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/horiText"
android:thumb="@drawable/switch_thumb"
android:progressDrawable="@drawable/progress_two"/>
对应progress的图片xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/background">
<shape>
<solid android:color="@color/grey_eee" />
<corners android:radius="5dp" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<solid android:color="@color/green" />
<corners android:radius="5dp" />
</shape>
</clip>
</item>
</layer-list>
下面要说的是这个竖向的seekbar,大致的思想就和网上很多写的一样,自定义一个verticalseekbar控件继承seekbar,在绘画的时候把canvas画布旋转90度,同时在onTouchEvent方法里,把拖动时需要的参数,由X变成Y。
我们在设置该控件的背景图片的时候发现,根本不起作用,或者说图片没有达到我们旋转的效果。因此我在onMeasure和onDraw方法里,去主动测量和绘制背景图片,达到我们预想的效果。
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.seekbarbackground);
int heightMeasure = MeasureSpec.makeMeasureSpec(bitmap.getHeight(), MeasureSpec.EXACTLY);
int widthtMeasure = MeasureSpec.makeMeasureSpec(bitmap.getWidth(), MeasureSpec.EXACTLY);
super.onMeasure(heightMeasure, widthtMeasure);
setMeasuredDimension(heightMeasure, widthtMeasure);
}
@Override
protected synchronized void onDraw(Canvas canvas) {
canvas.rotate(-90);
canvas.translate(-getHeight(), 0);
super.onDraw(canvas);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.seekbarbackground);
Paint paint = new Paint();
canvas.drawBitmap(bitmap, 0,0, paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (isInScrollingContainer()) {
mTouchDownY = event.getY();
} else {
setPressed(true);
invalidate();
onStartTrackingTouch();
trackTouchEvent(event);
attemptClaimDrag();
onSizeChanged(getWidth(), getHeight(), 0, 0);
}
break;
case MotionEvent.ACTION_MOVE:
if (mIsDragging) {
trackTouchEvent(event);
} else {
final float y = event.getY();
if (Math.abs(y - mTouchDownY) > mScaledTouchSlop) {
setPressed(true);
invalidate();
onStartTrackingTouch();
trackTouchEvent(event);
attemptClaimDrag();
}
}
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_UP:
if (mIsDragging) {
trackTouchEvent(event);
onStopTrackingTouch();
setPressed(false);
} else {
// Touch up when we never crossed the touch slop threshold
// should
// be interpreted as a tap-seek to that location.
onStartTrackingTouch();
trackTouchEvent(event);
onStopTrackingTouch();
}
onSizeChanged(getWidth(), getHeight(), 0, 0);
// ProgressBar doesn't know to repaint the thumb drawable
// in its inactive state when the touch stops (because the
// value has not apparently changed)
invalidate();
break;
}
return true;
}
private void trackTouchEvent(MotionEvent event) {
final int height = getHeight();
final int top = getPaddingTop();
final int bottom = getPaddingBottom();
final int available = height - top - bottom;
int y = (int) event.getY();
float scale;
float progress = 0;
// 下面是最小值
if (y > height - bottom) {
scale = 0.0f;
} else if (y < top) {
scale = 1.0f;
} else {
scale = (float) (available - y + top) / (float) available;
progress = mTouchProgressOffset;
}
final int max = getMax();
progress += scale * max;
setProgress((int) progress);
}