垂直的SeekBar:VerticalSeekBar

  1. public class VerticalSeekBar extends AbsSeekBar {  
  2.   
  3.     private Drawable mThumb;  
  4.   
  5.     public interface OnSeekBarChangeListener {  
  6.         void onProgressChanged(VerticalSeekBar VerticalSeekBar, int progress, boolean fromUser);  
  7.   
  8.         void onStartTrackingTouch(VerticalSeekBar VerticalSeekBar);  
  9.   
  10.         void onStopTrackingTouch(VerticalSeekBar VerticalSeekBar);  
  11.     }  
  12.   
  13.     private OnSeekBarChangeListener mOnSeekBarChangeListener;  
  14.   
  15.     public VerticalSeekBar(Context context) {  
  16.         this(context, null);  
  17.     }  
  18.   
  19.     public VerticalSeekBar(Context context, AttributeSet attrs) {  
  20.         this(context, attrs, android.R.attr.seekBarStyle);  
  21.     }  
  22.   
  23.     public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {  
  24.         super(context, attrs, defStyle);  
  25.     }  
  26.   
  27.     public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {  
  28.         mOnSeekBarChangeListener = l;  
  29.     }  
  30.   
  31.     void onStartTrackingTouch() {  
  32.         if (mOnSeekBarChangeListener != null) {  
  33.             mOnSeekBarChangeListener.onStartTrackingTouch(this);  
  34.         }  
  35.     }  
  36.   
  37.     void onStopTrackingTouch() {  
  38.         if (mOnSeekBarChangeListener != null) {  
  39.             mOnSeekBarChangeListener.onStopTrackingTouch(this);  
  40.         }  
  41.     }  
  42.   
  43.     void onProgressRefresh(float scale, boolean fromUser) {  
  44.         Drawable thumb = mThumb;  
  45.         if (thumb != null) {  
  46.             setThumbPos(getHeight(), thumb, scale, Integer.MIN_VALUE);  
  47.             invalidate();  
  48.         }  
  49.         if (mOnSeekBarChangeListener != null) {  
  50.             mOnSeekBarChangeListener.onProgressChanged(this, getProgress(), isPressed());  
  51.         }  
  52.     }  
  53.   
  54.     private void setThumbPos(int w, Drawable thumb, float scale, int gap) {  
  55.         int available = w - getPaddingLeft() - getPaddingRight();  
  56.         int thumbWidth = thumb.getIntrinsicWidth();  
  57.         int thumbHeight = thumb.getIntrinsicHeight();  
  58.         available -= thumbWidth;  
  59.   
  60.         // The extra space for the thumb to move on the track  
  61.         available += getThumbOffset() * 2;  
  62.   
  63.         int thumbPos = (int) (scale * available);  
  64.   
  65.         int topBound, bottomBound;  
  66.         if (gap == Integer.MIN_VALUE) {  
  67.             Rect oldBounds = thumb.getBounds();  
  68.             topBound = oldBounds.top;  
  69.             bottomBound = oldBounds.bottom;  
  70.         } else {  
  71.             topBound = gap;  
  72.             bottomBound = gap + thumbHeight;  
  73.         }  
  74.         thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);  
  75.     }  
  76.   
  77.     @Override  
  78.     protected void onDraw(Canvas c) {  
  79.         c.rotate(-90);// 反转90度,将水平SeekBar竖起来  
  80.         c.translate(-getHeight(), 0);// 将经过旋转后得到的VerticalSeekBar移到正确的位置,注意经旋转后宽高值互换  
  81.         super.onDraw(c);  
  82.     }  
  83.   
  84.     @Override  
  85.     protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  86.         super.onMeasure(heightMeasureSpec, widthMeasureSpec);  
  87.         setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());// 宽高值互换  
  88.     }  
  89.   
  90.     @Override  
  91.     public void setThumb(Drawable thumb) {  
  92.         mThumb = thumb;  
  93.         super.setThumb(thumb);  
  94.     }  
  95.   
  96.     @Override  
  97.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  98.         super.onSizeChanged(h, w, oldw, oldh);// 宽高值互换  
  99.     }  
  100.   
  101.     // 与源码完全相同,仅为调用宽高值互换处理的onStartTrackingTouch()方法  
  102.     @Override  
  103.     public boolean onTouchEvent(MotionEvent event) {  
  104.         if (!isEnabled()) {  
  105.             return false;  
  106.         }  
  107.         switch (event.getAction()) {  
  108.         case MotionEvent.ACTION_DOWN: {  
  109.             setPressed(true);  
  110.             onStartTrackingTouch();  
  111.             trackTouchEvent(event);  
  112.             break;  
  113.         }  
  114.   
  115.         case MotionEvent.ACTION_MOVE: {  
  116.             trackTouchEvent(event);  
  117.             attemptClaimDrag();  
  118.             break;  
  119.         }  
  120.   
  121.         case MotionEvent.ACTION_UP: {  
  122.             trackTouchEvent(event);  
  123.             onStopTrackingTouch();  
  124.             setPressed(false);  
  125.             // ProgressBar doesn't know to repaint the thumb drawable  
  126.             // in its inactive state when the touch stops (because the  
  127.             // value has not apparently changed)  
  128.             invalidate();  
  129.             break;  
  130.         }  
  131.   
  132.         case MotionEvent.ACTION_CANCEL: {  
  133.             onStopTrackingTouch();  
  134.             setPressed(false);  
  135.             invalidate(); // see above explanation  
  136.             break;  
  137.         }  
  138.   
  139.         default:  
  140.             break;  
  141.         }  
  142.         return true;  
  143.     }  
  144.   
  145.     // 宽高值互换处理  
  146.     private void trackTouchEvent(MotionEvent event) {  
  147.         final int height = getHeight();  
  148.         final int available = height - getPaddingBottom() - getPaddingTop();  
  149.         int Y = (int) event.getY();  
  150.         float scale;  
  151.         float progress = 0;  
  152.         if (Y > height - getPaddingBottom()) {  
  153.             scale = 0.0f;  
  154.         } else if (Y < getPaddingTop()) {  
  155.             scale = 1.0f;  
  156.         } else {  
  157.             scale = (float) (height - getPaddingBottom() - Y) / (float) available;  
  158.         }  
  159.         final int max = getMax();  
  160.         progress = scale * max;  
  161.         setProgress((int) progress);  
  162.     }  
  163.   
  164.     private void attemptClaimDrag() {  
  165.         if (getParent() != null) {  
  166.             getParent().requestDisallowInterceptTouchEvent(true);  
  167.         }  
  168.     }  
  169. }  
原文地址:https://www.cnblogs.com/wangfeng520/p/5481180.html