搬家后的博客链接: IT客栈 www.itkezhan.org
这几天需要用到垂直的 seekbar 但是android 包下翻了一下。发现没有,只能自己修改源码。
主要是继承 AbsSeekBar 然后修改下面这些方法
onProgressRefresh() //当进度条数据更新的时候,例如我们拖动滑动条的时候,这个方法被调用
setThumbPos() //这个方法是设置Thumb的位置
onDraw() //这个是负责画界面
onSizeChanged() //更新画布尺寸
onTouchEvent() //当触摸屏幕的时候被调用
trackTouchEvent() //当拖动滑动条的时候,这个被调用
还有就是添加一个接口这个接口是SeekBar 的一个内部接口 public interface OnSeekBarChangeListener
里面有三个方法:
public void onProgressChanged(VerticalSeekBar vBar, int progress,boolean fromUser);
public void onStartTrackingTouch(VerticalSeekBar vBar);
public void onStopTrackingTouch(VerticalSeekBar vBar);
这个接口主要是为外部提供监听。多说无益,大家看源代码明白一点。
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsSeekBar;
import android.widget.SeekBar;
public class VerticalSeekBar extends AbsSeekBar {
private int height = -1;
private int width = -1;
public interface OnSeekBarChangeListener
{
public void onProgressChanged(VerticalSeekBar vBar, int progress,boolean fromUser);
public void onStartTrackingTouch(VerticalSeekBar vBar);
public void onStopTrackingTouch(VerticalSeekBar vBar);
}
private OnSeekBarChangeListener mOnSeekBarChangeListener;
public VerticalSeekBar(Context context)
{
this(context, null);
}
public VerticalSeekBar(Context context, AttributeSet attrs)
{
this(context, attrs, android.R.attr.seekBarStyle);
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defstyle)
{
super(context, attrs, defstyle);
}
public void setOnSeekBarChangeListener(OnSeekBarChangeListener l)
{
mOnSeekBarChangeListener = l;
}
void onStartTrackingTouch()
{
if (mOnSeekBarChangeListener != null)
{
mOnSeekBarChangeListener.onStartTrackingTouch(this);
}
}
void onStopTrackingTouch()
{
if (mOnSeekBarChangeListener != null)
{
mOnSeekBarChangeListener.onStopTrackingTouch(this);
}
}
void onProgressRefresh(float scale, boolean fromUser)
{
Drawable thumb = null;
try
{
Field mThumb_f = this.getClass().getSuperclass().getDeclaredField("mThumb");
mThumb_f.setAccessible(true);
thumb = (Drawable)mThumb_f.get(this);
}
catch (Exception e)
{
e.printStackTrace();
}
setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
invalidate();
if (mOnSeekBarChangeListener != null) {
mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), fromUser);
}
}
private void setThumbPos(int w, Drawable thumb, float scale, int gap)
{
int available = 0;
try
{
int up = getPaddingTop();
int bottom = getPaddingBottom();
available = getHeight() - up - bottom;
int thumbWidth = thumb.getIntrinsicWidth();
int thumbHeight = thumb.getIntrinsicHeight();
available -= thumbWidth;
//The extra space for the thumb to move on the track
available += getThumbOffset() * 2;
int thumbPos = (int) (scale * available);
int topBound, bottomBound;
if (gap == Integer.MIN_VALUE) {
Rect oldBounds = thumb.getBounds();
topBound = oldBounds.top;
bottomBound = oldBounds.bottom;
} else {
topBound = gap;
bottomBound = gap + thumbHeight;
}
// Canvas will be translated, so 0,0 is where we start drawing
thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);
}
catch (Exception e)
{
e.printStackTrace();
}
}
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
width = 30;
height = View.MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(width, height);
}
protected void onDraw(Canvas c)
{
c.rotate(-90);
c.translate(-height,0);
super.onDraw(c);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(h, w, oldw, oldh);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
boolean mIsUserSeekable=true;
try
{
Field mIsUserSeekable_f = this.getClass().getSuperclass().getDeclaredField("mIsUserSeekable");
mIsUserSeekable_f.setAccessible(true);
mIsUserSeekable = mIsUserSeekable_f.getBoolean(this);
}
catch (Exception e1)
{
e1.printStackTrace();
}
if (!mIsUserSeekable || !isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setPressed(true);
onStartTrackingTouch();
trackTouchEvent(event);
break;
case MotionEvent.ACTION_MOVE:
trackTouchEvent(event);
Method attemptClaimDrag;
try
{
attemptClaimDrag = this.getClass().getSuperclass().getDeclaredMethod("attemptClaimDrag");
attemptClaimDrag.setAccessible(true);
attemptClaimDrag.invoke(this);
}
catch (Exception e)
{
e.printStackTrace();
}
break;
case MotionEvent.ACTION_UP:
trackTouchEvent(event);
onStopTrackingTouch();
setPressed(false);
// 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;
case MotionEvent.ACTION_CANCEL:
onStopTrackingTouch();
setPressed(false);
invalidate(); // see above explanation
break;
}
return true;
}
protected void trackTouchEvent(MotionEvent event)
{
final int height = getHeight();
final int available = height - getPaddingLeft() - getPaddingRight();
int y = (int)(height - event.getY());
float scale;
float progress = 0;
if (y < getPaddingLeft()) {
scale = 0.0f;
} else if (y > height - getPaddingRight()) {
scale = 1.0f;
} else {
scale = (float)(y - getPaddingLeft()) / (float)available;
float mTouchProgressOffset = 0.0f;
try
{
Field mTouchProgressOffset_f = this.getClass().getSuperclass().getDeclaredField("mTouchProgressOffset");
mTouchProgressOffset_f.setAccessible(true);
mTouchProgressOffset = mTouchProgressOffset_f.getFloat(this);
}
catch(Exception e)
{
e.printStackTrace();
}
progress = mTouchProgressOffset;
}
final int max = getMax();
progress += scale * max;
try
{
Method setProgress = this.getClass().getSuperclass().getSuperclass().getDeclaredMethod("setProgress", int.class,boolean.class);
setProgress.setAccessible(true);
setProgress.invoke(this, (int)progress, true);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
一个运行的截图
转载请注明出处,祝新年快乐。
本文链接:
http://blog.csdn.net/failure01/article/details/8577675
参考文档链接:
http://www.eoeandroid.com/thread-430-1-1.html
http://blog.csdn.net/saintswordsman/article/details/5248233