У меня есть приложение, которому требуется обработка событий необычным способом.
Что касается моего вопроса, позвольте мне сначала объяснить простой случай, когда текущая система обработки событий Android мне не подходит.
Предположим, что у меня есть FrameLayout (с этого момента я буду называть его ViewSwiper), что все представления, добавленные к нему, являются MATCH_PARENT X MATCH_PARENT (которое я буду называть PageView), он обрабатывает события, переводя фактическое представление и заменяя его в зависимости от направления перемещения. Этот компонент я уже сделал и работает правильно ( Использование анимации для просмотра просмотров ).
Но проблема заключается в том, что PageView я добавляю поверх него, в случае ImageViews, которые возвращают false в своем onTouchEvent, ViewSwiper будет обрабатывать события и позволять другому PageView выходить на экран, но если я добавлю ScrollView, все события будут потребляться прокруткой, и у ViewSwiper не будет возможности заменить PageView.
Итак, я понял, что возвращая false onTouchEvent ScrollView, родитель может предположить, что это события, я написал этот подкласс ScrollView, чтобы проверить его:
public class ScrollViewVertical extends ScrollView {
public ScrollViewVertical(Context context) {
super(context);
setOverScrollMode(OVER_SCROLL_ALWAYS);
setVerticalScrollBarEnabled(false);
}
public boolean onTouchEvent(MotionEvent evt) {
super.onTouchEvent(evt);
return false;
}
}
Но возврат false приводит к тому, что любые дальнейшие события отправляются родителю, но мне нужны эти события для ВЕРТИКАЛЬНОЙ прокрутки, поэтому у меня есть идея возвращать false только в том случае, если пользователь перемещается по ГОРИЗОНТАЛЬНОМУ, вот как выглядит мой код:
public class ScrollViewVertical extends ScrollView {
private MovementTracker moveTracker;
public ScrollViewVertical(Context context) {
super(context);
setOverScrollMode(OVER_SCROLL_ALWAYS);
setVerticalScrollBarEnabled(false);
moveTracker = new MovementTracker();
}
public boolean onTouchEvent(MotionEvent evt) {
if (moveTracker.track(evt))
if (moveTracker.getDirection() == Direction.HORIZONTAL)
return false;
return super.onTouchEvent(evt);
}
}
PS: MovementTracker вернет true в track() после некоторых событий и сообщит, в каком направлении движется пользователь.
Но в этом случае ScrollView продолжает получать события, поскольку возвращает true для первых событий.
Любые идеи о том, как я могу обрабатывать события в ViewSwiper, когда его дочерний элемент возвращает false (даже если возвращаются некоторые истинные значения).
PS: я могу дать больше информации об этом, если это необходимо, а также принять различные решения.
Основываясь на ответах, я попробовал следующее:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
onTouchEvent(ev);
return intercept;
}
public boolean onTouchEvent(MotionEvent evt) {
boolean x = super.onTouchEvent(evt);
if (moveTracker.track(evt)) {
intercept = moveTracker.getDirection() != Direction.VERTICAL;
if (!intercept)
getParent().requestDisallowInterceptTouchEvent(false);
}
return x;
}
Еще ничего.