How can I get a working vertical SeekBar in Android? How can I get a working vertical SeekBar in Android? android android

How can I get a working vertical SeekBar in Android?


Here is a working VerticalSeekBar implementation:

package android.widget;import android.content.Context;import android.graphics.Canvas;import android.util.AttributeSet;import android.view.MotionEvent;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;    }}

To implement it, create a new class in your project, choosing the right package:

There, paste the code and save it. Now use it in your XML layout:

<android.widget.VerticalSeekBar  android:id="@+id/seekBar1"  android:layout_width="wrap_content"  android:layout_height="200dp"  />


The code given in the accepted answer didn't intercept the onStartTrackingTouch and the onStopTrackingTouch events, so I've modified it to have more control over this two events.

Here is my code:

public class VerticalSeekBar extends SeekBar {private OnSeekBarChangeListener myListener;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);}@Overrideprotected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    super.onMeasure(heightMeasureSpec, widthMeasureSpec);    setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());}@Overridepublic void setOnSeekBarChangeListener(OnSeekBarChangeListener mListener){    this.myListener = mListener;}protected void onDraw(Canvas c) {    c.rotate(-90);    c.translate(-getHeight(), 0);    super.onDraw(c);}@Overridepublic boolean onTouchEvent(MotionEvent event) {    if (!isEnabled()) {        return false;    }    switch (event.getAction()) {        case MotionEvent.ACTION_DOWN:            if(myListener!=null)                myListener.onStartTrackingTouch(this);            break;        case MotionEvent.ACTION_MOVE:            setProgress(getMax() - (int) (getMax() * event.getY() / getHeight()));            onSizeChanged(getWidth(), getHeight(), 0, 0);            myListener.onProgressChanged(this, getMax() - (int) (getMax() * event.getY() / getHeight()), true);            break;        case MotionEvent.ACTION_UP:            myListener.onStopTrackingTouch(this);            break;        case MotionEvent.ACTION_CANCEL:            break;    }    return true;}}


I had problems while using this code with setProgress method. To solve them I suggest overriding setProgress and adding onSizeChanged call to it.