I need to disable swiping to open/close SlidingPaneLayout because my main view is a map. I\'ll open/close it using a button.
If you set the touchlistener and return true, it will consume the touch event and the widget will not handle it further.
slidingPaneLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return true;
}
});
This one is a bit tricky. If you always return true in onInterceptTouchEvent()
it will dispatch event to the hidden content below. I was able to achieve it like this:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return !slidingEnabled || super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (!slidingEnabled) {
// Careful here, view might be null
getChildAt(1).dispatchTouchEvent(ev);
return true;
}
return super.onTouchEvent(ev);
}
Subclass SlidingPaneLayout
, override onInterceptTouchEvent()
and make it always return false
. This will prevent SlidingPaneLayout
from handling touch events.
See http://developer.android.com/training/gestures/viewgroup.html for more information.
Update:
If touch events are not handled by the child view(s), the SlidingPaneLayout
's onTouchEvent()
method will be called nevertheless. To completely disable handling touch events also override onTouchEvent()
and always return false
.
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return false;
}
Note: The downside of this approach is that touch events still get dispatched to the second child view when it's only partly visible. So you might want to check out the other answers.
Building on Roman Zhilichs answer with two improvements.
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return !swipeEnabled || super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (!swipeEnabled) {
if (!getChildAt(0).dispatchTouchEvent(ev)) {
ev.offsetLocation(-getChildAt(0).getWidth(),0);
getChildAt(1).dispatchTouchEvent(ev);
}
return true;
}
return super.onTouchEvent(ev);
}
First, this tries to dispatch the MotionEvent to the first child before dispatching it to the second. This way, both child views stay interactive. Second, MotionsEvents dispatched to the second child view must be offset by the width of the first view. This assumes that the sliding pane slides in from the left, as is usual with SlidingPaneLayout.
If you want to disable the 'drag to open' event and enable user input once the layout is opened, you can use this
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
if(!isOpen()) return false;
return super.onInterceptTouchEvent(arg0);
}