Я довольно новичок в разработке приложений для Android, и я играл с жестами смахивания, используя Android SimpleOnGestureListener и ViewFlipper. Есть 3 дочерних элемента ViewFlipper, и каждый является ScrollView. Все они динамически заполняются при загрузке Activity, и после этого они не меняются. ScrollView - это место, где прикреплены SimpleOnGestureListeners.
Вот макет, который я использую:
+ ViewFlipper
++ ScrollView (x3, по одному на каждую страницу, каждая со следующим:)
+++ LinearLayout (вертикальный)
++++ TextView
++++ TableLayout (динамически заполненный с TableRows)
++++ Вид
Я расширил метод onFling общим учебным кодом, который вы можете найти в любом месте онлайн, и он прекрасно работает - за исключением случаев, когда один из ScrollViews не содержит достаточно контента для прокрутки.
Я сузил проблему до определения касания, переопределив и вызвав super для каждого из методов SimpleOnGestureListener, чтобы добавить печать в журнал.
Когда я пролистываю прокручиваемую страницу, я получаю что-то полное «inClick», «onScroll», «onFling» и т. Д. На слишком короткой странице для прокрутки я получаю «inClick», «onShowPress» «в onLongPress», и это только в том случае, если я касаюсь содержимого внутри дочерних элементов слишком короткого прокрутки - если я касаюсь в другом месте, я вообще не получаю никаких событий.
Идеи о том, что не так или как обнаружить жест смахивания, независимо от размера ScrollView?
РЕДАКТИРОВАТЬ: я определил, что когда я запускаю это на эмуляторе Android 2.2, в отличие от эмулятора Android 2.1u1 DroidX, который я использовал, он исчезает. Это воспроизводимо в нескольких средах.
У меня есть кое-что еще об этом; кажется, что onInterceptTouchEvent не вызывается для каждого события движения, когда представление прокрутки содержится в флиппере (или в WorkspaceView).
В частности, поведение, которое я обнаружил при изменении другого класса представления для исправления этой же самой проблемы (она не уникальна для флипперов), было следующим: обратите внимание, что это только Android 2.1:
Если представление прокрутки достаточно длинное для прокрутки, событие движения ACTION_DOWN перехватывается представлением ScrollView, и каждое последующее событие ACTION_MOVE проходит через onInterceptTouchEvent флиппера, где оно перехватывается и обрабатывается соответствующим образом. В Android 2.2 это происходит независимо от длины прокрутки.
Назад к 2.1: Если представление прокрутки недостаточно длинное для прокрутки, событие движения ACTION_DOWN не перехватывается просмотром прокрутки, но вместо этого возвращается к onTouchEvent флиппера. Все последующие события ACTION_MOVE того же жеста пропускают функцию onInterceptTouchEvent и переходят прямо к функции onTouchEvent!
Способ, которым я решил это, заключался в том, чтобы взять функциональность, имеющуюся в onTouchEvent, для событий ACTION_MOVE и преобразовать ее в свой собственный метод. Таким образом, у меня может быть вызов onTouchEvent onInterceptTouchEvent, за которым следует эта функциональность, если он обнаруживает, что событие ранее прошло необработанным.
case MotionEvent.ACTION_MOVE:
if (touchState == TOUCH_STATE_SCROLLING) {
handleScrollMove(ev);
} else {
// Log.d("workspace","caught a move touch event but not scrolling");
//NOTE: We will never hit this case in Android 2.2. This is to fix a 2.1 bug.
//We need to do the work of interceptTouchEvent here because we don't intercept the move
//on children who don't scroll.
Log.d("workspace","handling move from onTouch");
if(onInterceptTouchEvent(ev) && touchState == TOUCH_STATE_SCROLLING){
handleScrollMove(ev);
}
}
break;
Это из WorkspaceView.java (модификация Android Workspace.java, найденная в проекте andro-views в коде Google, и теперь здесь: Горизонтальная прокрутка "tab" между представлениями ). В случае, когда мы получаем событие перемещения и прокручиваем (что происходит, только если мы сознательно решили перехватить его - т. Е. Оно установлено в функции перехвата, поэтому мы уже были в функции перехвата), мы выполняем поведение движения мы желаем. Если мы получаем событие перемещения здесь, и мы не прокручиваем, то мы отправляем событие обратно через onIntercept, а затем проверяем, настроена ли сейчас прокрутка. Если это так, мы выполняем действие.
Это не элегантно, но работает!