Reputation: 1626
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
Reputation: 666
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
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