Пусть родительский представление предполагает MotionEvents, если ребенок возвращает ложь
-
27-10-2019 - |
Вопрос
У меня есть приложение, которое требует обработки событий необычно.
По моему вопросу, позвольте мне сначала объяснить простой случай, когда текущая система обработки событий Android не подходит для меня.
Предположим, что у меня есть Framelayout (который я с тех пор назову Viewswiper), что все добавленные на него виды - это match_parent x match_parent (который я вызову pageview), это обрабатывает события, переводя фактическое представление и заменить его на основе направления перемещения. Этот компонент, который я уже сделал и работал правильно ( Использование анимации для просмотра просмотров ).
Но проблема заключается в том, что в этом обзоре, которую я добавляю к ней, в случае обзоров изображений, которые возвращают false на его ontouchevent, ViewSwiper будет обрабатывать события и позволить другому просмотру страницы ввести экран, но если я добавлю ScrollView на это, все События будут употребляться с помощью свитка, и ViewSwiper не будет иметь возможности заменить просмотр страниц.
Поэтому я выяснил, что возвращение False Ontouchevent of 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 сделает какие -либо дальнейшие события, чтобы отправиться в отправку родителям, но мне нужны эти события для вертикальной прокрутки, поэтому у меня есть идея возвращать флаги только в том случае, если пользователь перемещается по горизонтали, вот как выглядит мой код:
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 On Cround () после некоторых событий и расскажет о том, в каком направлении движется пользователь.
Но в этом случае Scrollview продолжает получать события, так как он возвращается в первые события.
Любые идеи о том, как я могу справиться с событиями на ViewSwiper, когда ребенок возвращает ложные (даже если некоторые трюки возвращаются).
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;
}
Еще ничего.
Решение
Попробуйте это в onTouchEvent()
Scrollview
//if (evt.getAction() == MotionEvent.ACTION_MOVE) {
if (moveTracker.track(evt)){
if (moveTracker.getDirection() == Direction.VERTICAL){
//Or the direction you want the scrollview keep moving
getParent().requestDisallowInterceptTouchEvent(true);
}
}
return true;
Обновлять
Пожалуйста, попробуйте следующее на пользовательском ScrollView
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
super.dispatchTouchEvent(ev);
return false;
}
И ничего больше
Таким образом, я предполагаю, что MotionEvent будет работать на обоих представлениях. И поскольку они не конфликтуют (один вертикальна, другой горизонталь), это может работать
Другие советы
Основываясь на ответе от Sleedwire, я пришел к следующему решению:
На Viewswiper
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if(!super.dispatchTouchEvent(ev))
onTouchEvent(ev);
return true;
}
И на Scrollhorizontal я возвращаю False на DispatchTouchEvent, когда мне больше не нужно.