Beowulf Bjornson
Beowulf Bjornson

Reputation: 1626

Increasing touch priority of a SeekBar

I have a SeekBar inside a HorizontalScrollView and am finding it very hard to grab the handle and move it. If I don't touch exactly on the handle, the HorizontalScrollView will receive and consume the touch event. Is there a way to increase the priority of the SeekBar so it will have the normal "range" for touch events or is this just a bad idea/design and I should avoid it?

Upvotes: 1

Views: 2979

Answers (2)

Here is an other way to fix this issue without extends a Frame layout.
The idea is to disable the touch event of the HorizontalScrollView when you touch the SeekBar.
So, when you initialize the view for example, you can define something like this:

protected void onCreate(final Bundle savedInstanceState)
{

    [...]

    final HorizontalScrollView scrollView = (HorizontalScrollView) findViewById(R.id.vo_cw_hsv);
    final SeekBar opacitySeekBar = (SeekBar) findViewById(R.id.vo_cw_seekbar);
    opacitySeekBar.setOnTouchListener(new OnTouchListener()
    {
      @Override
      public boolean onTouch(final View view, final MotionEvent event)
      {
        if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE)

          scrollView.requestDisallowInterceptTouchEvent(true);

        return false;
      }
    });

    [...]

}

For more information you can read the doc on ViewParent class: http://developer.android.com/reference/android/view/ViewParent.html#requestDisallowInterceptTouchEvent(boolean)

Upvotes: 5

Beowulf Bjornson
Beowulf Bjornson

Reputation: 1626

I "solved" it by doing the following:

NOTE: My scroll layout is lockable, as explained here: https://stackoverflow.com/a/5763815/1067721 (just pay atention to my answer a little bit lower, I found that bit to be important)

I then wrapped my seekbar in a FrameLayout able to intercept touch events:

public class InterceptFrameLayout extends FrameLayout {

    private OnTouchListener mListener;

    public InterceptFrameLayout(Context context) {
        super(context);
    }

    public InterceptFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public InterceptFrameLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onInterceptTouchEvent (MotionEvent ev) {
        return onTouchEvent(ev);
    }

    @Override
    public void setOnTouchListener (View.OnTouchListener l) {
        mListener = l;
    }

    @Override
    public boolean onTouchEvent (MotionEvent ev) {
        if (mListener != null) {
            return mListener.onTouch(this, ev);
        } else {
            return super.onTouchEvent(ev);
        }
    }
}

And then, on my Fragment, I implemented the listener and let the SeekBar consume the event:

    volWrapper.setOnTouchListener(new OnTouchListener() {           
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    mHostingScroll.setScrollable(false);
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    mHostingScroll.setScrollable(true);
                    break;
                }
            }
            return volumeBar.onTouchEvent(event);
        }
    });

Upvotes: 0

Related Questions