Reputation: 2539
I have a Gallery with an adapter which supplies it ScrollViews as its child views. I need to make sure that the touch events are handled correctly and as expected:
Without overriding any methods, the scroll view is the only thing that scrolls - the gallery never scrolls.
So I understand I need to use onInterceptTouchEvent(...) in the gallery to decide to take over a certain series of MotionEvents but I am unsure how to check if the touch is horizontal or vertical in nature.
Upvotes: 6
Views: 3605
Reputation: 341
I have tried solution provided by Warlax. It moved me forward but unfortunately it breaks normal gallery behavior in some rare cases. (For example it doesn't stop on touch while scrolling) So I did more research and came up with the following solution.
public class TouchInterceptingGallery extends Gallery {
public TouchInterceptingGallery(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public TouchInterceptingGallery(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TouchInterceptingGallery(Context context) {
super(context);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
this.onTouchEvent(ev);
return false;
}
}
Upvotes: 0
Reputation: 2539
OK, after some major fiddling and logcat hacking, here's the solution:
public class SwipeInterceptingGallery extends Gallery {
private float mInitialX;
private float mInitialY;
private boolean mNeedToRebase;
private boolean mIgnore;
public SwipeInterceptingGallery(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public SwipeInterceptingGallery(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SwipeInterceptingGallery(Context context) {
super(context);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
if (mNeedToRebase) {
mNeedToRebase = false;
distanceX = 0;
}
return super.onScroll(e1, e2, distanceX, distanceY);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN: {
mIgnore = false;
mNeedToRebase = true;
mInitialX = e.getX();
mInitialY = e.getY();
return false;
}
case MotionEvent.ACTION_MOVE: {
if (!mIgnore) {
float deltaX = Math.abs(e.getX() - mInitialX);
float deltaY = Math.abs(e.getY() - mInitialY);
mIgnore = deltaX < deltaY;
return !mIgnore;
}
return false;
}
default: {
return super.onInterceptTouchEvent(e);
}
}
}
}
Upvotes: 19