国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android實現垂直進度條VerticalSeekBar

2019-12-12 00:41:42
字體:
來源:轉載
供稿:網友

本文實例為大家分享了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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 东丰县| 汝阳县| 襄汾县| 东安县| 竹山县| 油尖旺区| 苍溪县| 阳春市| 隆子县| 红原县| 抚顺县| 凉城县| 邵阳县| 罗平县| 长乐市| 铜川市| 沽源县| 克山县| 怀宁县| 广水市| 丹棱县| 新宾| 汪清县| 建平县| 黑山县| 九龙坡区| 仁化县| 临西县| 贵港市| 北宁市| 竹山县| 色达县| 台南县| 云阳县| 金湖县| 章丘市| 磐安县| 綦江县| 安达市| 黑山县| 八宿县|