Android实现垂直进度条VerticalSeekBar

本文实例为大家分享了Android实现垂直进度条的具体代码,供大家参考,具体内容如下

水平的进度条见多了,总会想见个垂直的进度条开开眼。今天咱就试试。

要说原理也简单,就是把宽高倒置,其他的理论上都不需要动,发现问题再补补也就行了。

官方提供

官方是提供了垂直进度条的例子源码的,位置在android-sdk-windows\sources\android-23\com\android\example\rscamera\VerticalSeekBar.java,当然首先你SDK中要有Android 6.0。

VerticalSeekBar.java

/**

* Class to create a vertical slider

*/

public class VerticalSeekBar extends SeekBar {

public VerticalSeekBar(Context context) {

super(context);

}

public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}

public VerticalSeekBar(Context context, AttributeSet attrs) {

super(context, attrs);

}

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(h, w, oldh, oldw);

}

@Override

protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(heightMeasureSpec, widthMeasureSpec);

setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());

}

protected void onDraw(Canvas c) {

c.rotate(-90);

c.translate(-getHeight(), 0);

super.onDraw(c);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

if (!isEnabled()) {

return false;

}

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

case MotionEvent.ACTION_MOVE:

case MotionEvent.ACTION_UP:

setProgress(getMax() - (int) (getMax() * event.getY() / getHeight()));

onSizeChanged(getWidth(), getHeight(), 0, 0);

break;

case MotionEvent.ACTION_CANCEL:

break;

}

return true;

}

}

继承SeekBar是最简单快捷的,不用重写太多方法,只需要把

onMeasure

onSizeChanged

onDraw

三个方法作一些改动;但也有一些问题,比如只能响应onPregress方法,为了让他能响应onStartTrackingTouch和onStopTrackingTouch方法,只好再加一些代码,于是有了改进版。

稍作改进

VerticalSeekBar2.java

public class VerticalSeekBar2 extends SeekBar {

private Drawable mThumb;

private OnSeekBarChangeListener mOnSeekBarChangeListener;

public VerticalSeekBar2(Context context) {

super(context);

}

public VerticalSeekBar2(Context context, AttributeSet attrs) {

super(context, attrs);

}

public VerticalSeekBar2(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}

public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {

mOnSeekBarChangeListener = l;

}

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(h, w, oldh, oldw);

}

@Override

protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(heightMeasureSpec, widthMeasureSpec);

setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());

}

protected void onDraw(Canvas c) {

c.rotate(-90);

c.translate(-getHeight(), 0);

super.onDraw(c);

}

void onProgressRefresh(float scale, boolean fromUser) {

Drawable thumb = mThumb;

if (thumb != null) {

setThumbPos(getHeight(), 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 = w - getPaddingLeft() - getPaddingRight();

int thumbWidth = thumb.getIntrinsicWidth();

int thumbHeight = thumb.getIntrinsicHeight();

int thumbPos = (int) (scale * available + 0.5f);

// int topBound = getWidth() / 2 - thumbHeight / 2 - getPaddingTop();

// int bottomBound = getWidth() / 2 + thumbHeight / 2 - getPaddingTop();

int topBound, bottomBound;

if (gap == Integer.MIN_VALUE) {

Rect oldBounds = thumb.getBounds();

topBound = oldBounds.top;

bottomBound = oldBounds.bottom;

} else {

topBound = gap;

bottomBound = gap + thumbHeight;

}

thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);

}

public void setThumb(Drawable thumb) {

mThumb = thumb;

super.setThumb(thumb);

}

void onStartTrackingTouch() {

if (mOnSeekBarChangeListener != null) {

mOnSeekBarChangeListener.onStartTrackingTouch(this);

}

}

void onStopTrackingTouch() {

if (mOnSeekBarChangeListener != null) {

mOnSeekBarChangeListener.onStopTrackingTouch(this);

}

}

private void attemptClaimDrag() {

if (getParent() != null) {

getParent().requestDisallowInterceptTouchEvent(true);

}

}

@Override

public boolean onTouchEvent(MotionEvent event) {

if (!isEnabled()) {

return false;

}

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

setPressed(true);

onStartTrackingTouch();

break;

case MotionEvent.ACTION_MOVE:

attemptClaimDrag();

setProgress(getMax() - (int) (getMax() * event.getY() / getHeight()));

break;

case MotionEvent.ACTION_UP:

onStopTrackingTouch();

setPressed(false);

break;

case MotionEvent.ACTION_CANCEL:

onStopTrackingTouch();

setPressed(false);

break;

}

return true;

}

为了响应另外两个不知道怎么就被onPregress抛弃的方法,添了这么多代码真是罪过,不过都是从SeekBar的父类AbsSeekBar中仿写过来的,逻辑稍作改动就能用。

对比测试

上图。

左边是官方例子中的,右边是改进过的。

测试源码:垂直进度条VerticalSeekBar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 Android实现垂直进度条VerticalSeekBar 的全部内容, 来源链接: utcz.com/p/240867.html

回到顶部