Scrollview doesn't swipe when it's too short to scroll

I'm pretty new to Android app development, and I've been playing around with swipe gestures using Android's SimpleOnGestureListener and a ViewFlipper. There are 3 children of the ViewFlipper, and each is a ScrollView. They're all dynamically populated when the Activity loads, and they don't change after that. The ScrollView is where the SimpleOnGestureListeners are attached.

Here's the layout I'm using:
+ ViewFlipper
++ ScrollView (x3, по одному на каждую страницу, каждая со следующим:)
+++ LinearLayout (вертикальный)
++++ TextView
++++ TableLayout (динамически заполненный с TableRows)
++++ View

Я расширил метод 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, и теперь здесь: Горизонтальная прокрутка «табуляции» между представлениями ). В случае, когда мы получаем событие перемещения и прокручиваем (что происходит, только если мы сознательно решили перехватить его - т. Е. Оно установлено в функции перехвата, поэтому мы уже были в функции перехвата), мы выполняем поведение движения мы желаем. Если мы получаем событие перемещения здесь и не прокручиваем, то мы отправляем событие обратно через onIntercept, а затем проверяем, настроена ли сейчас прокрутка. Если это так, мы выполняем действие.

Это не элегантно, но работает!

8
задан Community 23 May 2017 в 12:13
поделиться

1 ответ

Попробуйте установить android: fillViewport = "true" в XML макета для каждого из ScrollView s. Это говорит о том, что ScrollView должен быть такого же размера, как и представление, в котором он содержится.

1
ответ дан 5 December 2019 в 20:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: