垂直的SeekBar:VerticalSeekBar

这是我找到的一个比较好用的垂直的SeekBar代码:


[java] view plaincopy在CODE上查看代码片派生到我的代码片
public class VerticalSeekBar extends AbsSeekBar {  
  
    private Drawable mThumb;  
  
    public interface OnSeekBarChangeListener {  
        void onProgressChanged(VerticalSeekBar VerticalSeekBar, int progress, boolean fromUser);  
  
        void onStartTrackingTouch(VerticalSeekBar VerticalSeekBar);  
  
        void onStopTrackingTouch(VerticalSeekBar VerticalSeekBar);  
    }  
  
    private OnSeekBarChangeListener mOnSeekBarChangeListener;  
  
    public VerticalSeekBar(Context context) {  
        this(context, null);  
    }  
  
    public VerticalSeekBar(Context context, AttributeSet attrs) {  
        this(context, attrs, android.R.attr.seekBarStyle);  
    }  
  
    public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {  
        super(context, attrs, defStyle);  
    }  
  
    public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {  
        mOnSeekBarChangeListener = l;  
    }  
  
    void onStartTrackingTouch() {  
        if (mOnSeekBarChangeListener != null) {  
            mOnSeekBarChangeListener.onStartTrackingTouch(this);  
        }  
    }  
  
    void onStopTrackingTouch() {  
        if (mOnSeekBarChangeListener != null) {  
            mOnSeekBarChangeListener.onStopTrackingTouch(this);  
        }  
    }  
  
    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(), isPressed());  
        }  
    }  
  
    private void setThumbPos(int w, Drawable thumb, float scale, int gap) {  
        int available = w - getPaddingLeft() - getPaddingRight();  
        int thumbWidth = thumb.getIntrinsicWidth();  
        int thumbHeight = thumb.getIntrinsicHeight();  
        available -= thumbWidth;  
  
        // The extra space for the thumb to move on the track  
        available += getThumbOffset() * 2;  
  
        int thumbPos = (int) (scale * available);  
  
        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);  
    }  
  
    @Override  
    protected void onDraw(Canvas c) {  
        c.rotate(-90);// 反转90度,将水平SeekBar竖起来  
        c.translate(-getHeight(), 0);// 将经过旋转后得到的VerticalSeekBar移到正确的位置,注意经旋转后宽高值互换  
        super.onDraw(c);  
    }  
  
    @Override  
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);  
        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());// 宽高值互换  
    }  
  
    @Override  
    public void setThumb(Drawable thumb) {  
        mThumb = thumb;  
        super.setThumb(thumb);  
    }  
  
    @Override  
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
        super.onSizeChanged(h, w, oldw, oldh);// 宽高值互换  
    }  
  
    // 与源码完全相同,仅为调用宽高值互换处理的onStartTrackingTouch()方法  
    @Override  
    public boolean onTouchEvent(MotionEvent event) {  
        if (!isEnabled()) {  
            return false;  
        }  
        switch (event.getAction()) {  
        case MotionEvent.ACTION_DOWN: {  
            setPressed(true);  
            onStartTrackingTouch();  
            trackTouchEvent(event);  
            break;  
        }  
  
        case MotionEvent.ACTION_MOVE: {  
            trackTouchEvent(event);  
            attemptClaimDrag();  
            break;  
        }  
  
        case MotionEvent.ACTION_UP: {  
            trackTouchEvent(event);  
            onStopTrackingTouch();  
            setPressed(false);  
            // ProgressBar doesn't know to repaint the thumb drawable  
            // in its inactive state when the touch stops (because the  
            // value has not apparently changed)  
            invalidate();  
            break;  
        }  
  
        case MotionEvent.ACTION_CANCEL: {  
            onStopTrackingTouch();  
            setPressed(false);  
            invalidate(); // see above explanation  
            break;  
        }  
  
        default:  
            break;  
        }  
        return true;  
    }  
  
    // 宽高值互换处理  
    private void trackTouchEvent(MotionEvent event) {  
        final int height = getHeight();  
        final int available = height - getPaddingBottom() - getPaddingTop();  
        int Y = (int) event.getY();  
        float scale;  
        float progress = 0;  
        if (Y > height - getPaddingBottom()) {  
            scale = 0.0f;  
        } else if (Y < getPaddingTop()) {  
            scale = 1.0f;  
        } else {  
            scale = (float) (height - getPaddingBottom() - Y) / (float) available;  
        }  
        final int max = getMax();  
        progress = scale * max;  
        setProgress((int) progress);  
    }  
  
    private void attemptClaimDrag() {  
        if (getParent() != null) {  
            getParent().requestDisallowInterceptTouchEvent(true);  
        }  
    }  
}  

放上来保存一下下,有需要的同学可以直接拿走 -v-


2014-04-02

请使用的同学们注意,onProgressRefresh()这个方法,一定要保证其不被混淆掉。这个方法,实际上它的作用是重写了父类的方法,但加上@Override会报错,请一定注意。
原文地址:https://www.cnblogs.com/Free-Thinker/p/4581565.html