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

android竖直seekbar

2014-04-02 11:50 302 查看
参考了:http://blog.csdn.net/failure01/article/details/8577675

做了如下修改:

1,修改宽度使宽度可以调节;

2,修改了按键事件,使之响应遥控器的上下按键,并且释放了左右按键;

public class VerticalSeekBar extends AbsSeekBar {

private String TAG = "VerticalSeekBar";
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 = View.MeasureSpec.getSize(widthMeasureSpec);
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;
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.i(TAG, "onkeydown keycode=" + keyCode);
if (isEnabled()) {
int progress = getProgress();
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_DOWN:
if (progress <= 0)
break;
setProgress(progress - getKeyProgressIncrement());
return true;

case KeyEvent.KEYCODE_DPAD_UP:
if (progress >= getMax())
break;
setProgress(progress + getKeyProgressIncrement());
return true;
//释放左右按键
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT:
return false;
}
}
return super.onKeyDown(keyCode, event);
}

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();
}
}
}


2,使用:新建xml文件在用到的地方添加VerticalSeekBar

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >

<com.mktech.component.VerticalSeekBar
android:id="@+id/verticalseekbar_voice"
android:layout_width="5dp"
android:layout_height="200dip"
android:focusable="true"
android:maxWidth="5dp"
android:minWidth="5dp"
android:progressDrawable="@xml/seekbar_style"
android:thumb="@null"
android:thumbOffset="10dp" />
<!-- android:progressDrawable="@xml/progress" -->

</LinearLayout>


注意:补充一点,重写竖直的seekbar后对xml的布局支持不是太好,也不能居中,可能是因为seekbar是水平控件,对竖直的支持不是太好的缘故;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android控件 SeekBar