У меня была похожая проблема, и я решил ее путем переопределения Галереи и реализации onInterceptTouchEvent, чтобы гарантировать, что события перемещения перехватываются Галереей, а все остальные события обрабатываются нормально.
При возврате true в onInterceptTouchEvent все последующие события касания в этой последовательности касаний отправляются в это представление, а значение false оставляет событие для своих детей.
TouchSlop необходим, так как при выполнении щелчка иногда происходит небольшое движение.
Хотелось бы заявить об этом как о своей идее, но основы кода были получены из кода запуска Android по умолчанию.
public class MyGallery extends Gallery{
private MotionEvent downEvent;
private int touchSlop;
private float lastMotionY;
private float lastMotionX;
public MyGallery(Context context) {
super(context);
initTouchSlop();
}
private void initTouchSlop() {
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
touchSlop = configuration.getScaledTouchSlop();
}
@Override public boolean onInterceptTouchEvent(MotionEvent ev) {
final float x = ev.getX();
final float y = ev.getY();
switch (ev.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_MOVE: {
final int xDiff = (int) Math.abs(x - lastMotionX);
final int yDiff = (int) Math.abs(y - lastMotionY);
// have we moved enough to consider this a scroll
if (xDiff > touchSlop || yDiff > touchSlop) {
// this is the event we want, but we need to resend the Down event as this could have been consumed by a child
Log.d(TAG, "Move event detected: Start intercepting touch events");
if (downEvent != null) this.onTouchEvent(downEvent);
downEvent = null;
return true;
}
return false;
}
case MotionEvent.ACTION_DOWN: {
// need to save the on down event incase this is going to be a scroll
downEvent = MotionEvent.obtain(ev);
lastMotionX = x;
lastMotionY = y;
return false;
}
default: {
// if this is not a down or scroll event then it is not for us
downEvent = null;
return false;
}
}
}