Organizational Research By

Surprising Reserch Topic

how can i get a working vertical seekbar in android


how can i get a working vertical seekbar in android  using -'android,seekbar'

I've implemented the commonly-pointed-to VerticalSeekBar post here. As it is, the SeekBar operates a little quirky. Here is my slightly adapted onTouchEvent() from that example:

public boolean onTouchEvent(MotionEvent event)
    {
            xPos = event.getX();
            yPos = event.getY();
            oOffset = this.getThumbOffset();
            oProgress = this.getProgress();

            //Code from example - Not working
            //this.setThumbOffset( progress * (this.getBottom()-this.getTop()) );

            this.setProgress((int)(29*yPos/this.getBottom()));
            return true;
    }


I've managed to implement one VerticalSeekBar in which the progress updates as expected and is fully-functional, but the thumb does not follow suit. This is only a graphical glitch, so I'm overlooking it for now. But, it would be nice to have that working. This SeekBar has max = 20.

However, I tried implementing another VerticalSeekBar with max = 1000. Obviously, it uses the same code, so you'd assume the same behavior. I'm only able to achieve a progress of 0~35, even as my finger slides beyond the SeekBar and eventually off the screen. If I just tap near the end of the progress bar (which should be progress ~ 900) it returns a progress of about 35 and the yellow progress bar reflects that value by staying near the top.

My question is: Does anyone have a link to a working vertical SeekBar, or know how to adapt this particular example?
    

asked Oct 13, 2015 by devkumargupta
0 votes
8 views



Related Hot Questions

5 Answers

0 votes

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:


answered Oct 13, 2015 by sandeep bhadauria
0 votes

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);
}

@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(heightMeasureSpec, widthMeasureSpec);
    setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}

@Override
public void setOnSeekBarChangeListener(OnSeekBarChangeListener mListener){
    this.myListener = mListener;
}

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:
            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;
}
}
answered Oct 13, 2015 by vimaldas2005
0 votes

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

   private int x,y,z,w;
   protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(h, w, oldh, oldw);
        this.x=w;
        this.y=h;
        this.z=oldw;
        this.w=oldh;
    }
        @Override
        public synchronized void setProgress(int progress) {

            super.setProgress(progress);

                onSizeChanged(x, y, z, w);

        }

selected hover actions are performed by adding the following code:

1.setPressed(true);setSelected(true);//Add this in ACTION_DOWN

2.setPressed(false);setSelected(false);//Add this in ACTION_UP

And Write code for selected hover options in ur xml.

" rel="nofollow" target="_blank">http://schemas.android.com/apk/res/android">
    
    
    

This is working for me...

answered Oct 13, 2015 by yogeshplv
0 votes

Thanks to Paul Tsupikoff, Fatal1ty2787 and Ramesh for this excellent code.

Personally, I wanted a vertical slider that is upside-down compared to the given code. In other words, the value increases, rather than decreases, the lower the thumb. Changing four lines seems to have taken care of this.

First, I changed the onDraw() method as originally given by Paul. The rotate() and translate() calls now have these arguments:

c.rotate(90);
c.translate(0, -getWidth());

Then I made two changes to the ACTION_MOVE case in onTouchEvent() as given by Fatal1ty2787. The call to setProgress() now looks like this:

setProgress((int) (getMax() * event.getY() / getHeight()));

Finally, the call to onProgressChanged() looks like this:

myListener.onProgressChanged(this, (int) (getMax() * event.getY() / getHeight()), true);

Now, if only Google shared our interest in this feature....

answered Oct 13, 2015 by balvant maurya
0 votes

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

answered Oct 13, 2015 by vimaldas2005

...