本文實(shí)例為大家分享了Android實(shí)現(xiàn)垂直進(jìn)度條的具體代碼,供大家參考,具體內(nèi)容如下
水平的進(jìn)度條見多了,總會(huì)想見個(gè)垂直的進(jìn)度條開開眼。今天咱就試試。
要說原理也簡單,就是把寬高倒置,其他的理論上都不需要?jiǎng)樱l(fā)現(xiàn)問題再補(bǔ)補(bǔ)也就行了。
官方提供
官方是提供了垂直進(jìn)度條的例子源碼的,位置在android-sdk-windows/sources/android-23/com/android/example/rscamera/VerticalSeekBar.java,當(dāng)然首先你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
三個(gè)方法作一些改動(dòng);但也有一些問題,比如只能響應(yīng)onPregress方法,為了讓他能響應(yīng)onStartTrackingTouch和onStopTrackingTouch方法,只好再加一些代碼,于是有了改進(jìn)版。
稍作改進(jìn)
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; }
為了響應(yīng)另外兩個(gè)不知道怎么就被onPregress拋棄的方法,添了這么多代碼真是罪過,不過都是從SeekBar的父類AbsSeekBar中仿寫過來的,邏輯稍作改動(dòng)就能用。
對(duì)比測(cè)試
上圖。
左邊是官方例子中的,右邊是改進(jìn)過的。
測(cè)試源碼:垂直進(jìn)度條VerticalSeekBar
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。
新聞熱點(diǎn)
疑難解答
網(wǎng)友關(guān)注