Перелистывание / переключение вкладок в сочетании с ScrollView? - PullRequest
23 голосов
/ 24 февраля 2011

Лучшее, что я мог найти по этой конкретной проблеме (хотя я не использую Галерею): ScrollView и Галерея, мешающие - на самом деле не дает конкретного ответа. И моя реализация не использует галерею, очевидно.

Перейдите к следующей жирной части для интересной части

Итак, я получил Fling / Swipe / Flick / как хотите, чтобы он назывался, чтобы работать некоторое время назад над моим приложением. Вдохновение было собрано из нескольких разных мест, некоторые из которых были "базовым обнаружением жестов" здесь, в Переполнении стека ( Обнаружение жестов Fling при разметке сетки ), Code Shogun (http://www.codeshogun.com/blog/2009/04/16/how-to-implement-swipe-action-in-android/) и Developing Android (http://developingandroid.blogspot.com/2009/09/implementing-swipe-gesture.html), но я не использую ViewFlipper в своем приложении. Когда происходит бросок, я просто меняю вкладку (оборачиваясь на концах).

Теперь некоторые из моих вкладок содержат ScrollViews. Эти ScrollViews, очевидно, отвечают на прокрутки вверх / вниз, чтобы позволить вам просматривать все данные внутри него, что неудивительно. Проблема заключается в том, что функция прокрутки этих ScrollViews перезаписывает мой жест броска. Я не могу бросить внутри ScrollView (прокрутка просто отлично), но он работает безупречно за их пределами (на той же вкладке, на других представлениях, таких как TableRow или что-то еще).

Я также быстро взглянул на http://blog.velir.com/index.php/2010/11/17/android-snapping-horizontal-scroll/, который предоставляет способ реализации HorizontalScrollView. Но он по-прежнему обрабатывает жесты через класс, который расширяет SimpleOnGestureListener (и перезаписывает onFling), который является той же реализацией, что и я (что заставляет меня думать, что это не очень поможет). Исходный код ScrollView от Google: http://google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/widget/ScrollView.java&d=3

Есть ли способ заставить мою реализацию Swipe и ScrollView работать вместе без усилий?

Вот в чем проблема, наверное. ScrollView.java также использует метод onTouchEvent и документацию для состояний onTouchEvent for Activity:

"Вызывается, когда событие сенсорного экрана было не обрабатывается ни одним из представленных в Это. Это наиболее полезно для обработки сенсорные события, которые происходят за пределами ваши границы окна, где нет чтобы получить его. "

Итак, ScrollView «переопределяет» его - что мне делать? Нет ли способа убедиться, что оба проверены? Мой onTouchEvent, который не срабатывает, когда onTouchEvent обрабатывается ScrollView:

@Override
/** Used for swipe gestures */
public boolean onTouchEvent(MotionEvent event) {
    if (gestureDetector.onTouchEvent(event))
        return true;
    else
        return false;
}

Более общий исходный код ниже, он, вероятно, не очень важен. GestDetector внутри моего класса Tabs со связанным слушателем:

    // Gestures
    gestureDetector = new GestureDetector(new MyGestureDetector());
    gestureListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (gestureDetector.onTouchEvent(event)) {
                return true;
            }
            return false;
        }
    };

Мой класс жестов, который является вложенным классом моего класса Tabs (который расширяет TabActivity) - он такой же, как и любой другой код, который вы найдете по этому вопросу:

/** GestureDetector used to swipe between classes */
class MyGestureDetector extends SimpleOnGestureListener {
    TabHost tabHost = getTabHost(); 

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        try {
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) return false;
            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                // my tab code
                return true;
            } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                // my tab code
                return true;
            }
        } catch (Exception e) {
            Log.e("MyGestureDetector onFling", e.toString());
        }
        return false;
    }
}

Ответы [ 3 ]

18 голосов
/ 28 февраля 2011

Я бы посоветовал вам взглянуть на исходный код приложения Google I / O 2010, поскольку их реализация FlingableTabHost может решить эту проблему:

http://iosched.googlecode.com/svn/trunk/src/com/google/android/apps/iosched/ui/ScheduleActivity.java

Я думаю, что ключ к расширению TabHost и переопределению его onInterceptTouchEvent метода.

0 голосов
/ 01 октября 2011

Несмотря на это, я нашел метод onFling очень ненадежным.Я перезаписываю метод onScroll в SimpleGestureDetector и определяю свой onInterceptTouchEvent как:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    //Call super first because it does some hidden motion event handling
    boolean result = super.onInterceptTouchEvent(ev);
    if (this.mGestureScanner.onTouchEvent(ev)) return true;
    return result;
}
0 голосов
/ 17 марта 2011

В поисках решения аналогичной проблемы, с которой я столкнулся, я наткнулся на этот бит:

eventsInterceptionEnabled: если установлено значение true, это свойство сообщает оверлею украсть события у его дочерних элементов.как только он узнает, что пользователь действительно рисует жест.Это полезно, когда под оверлеем есть прокручиваемое представление, чтобы избежать прокрутки нижележащего потомка, когда пользователь рисует свой жест

С сайта Android Dev , он говорит об использовании этогоатрибут в корне <android.gesture.GestureOverlayView> в файле макета.

...