本文實例為大家分享了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
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。