Swipe / Fling tab-zmiana w połączeniu z ScrollView?

Najlepsze, jakie znalazłem na ten konkretny temat (chociaż nie używam galerii): ScrollView i Gallery interfering - nie daje jednak konkretnej odpowiedzi. A moja realizacja nie korzysta oczywiście z galerii.

Przejdź do następnej pogrubionej części dla interesującej części

Więc dostałem Fling / Swipe / Flick / cokolwiek chcesz nazwać to działa jakiś czas temu na mojej aplikacji. Inspiracje czerpano z kilku różnych miejsca, niektóre z nich są "podstawowe wykrywanie gestów" tutaj na Stack Overflow (wykrywanie gestów Fling na układzie siatki ), Code Shogun ( http://www.codeshogun.com/blog/2009/04/16/how-to-implement-swipe-action-in-android/) i rozwój Androida ( http://developingandroid.blogspot.com/2009/09/implementing-swipe-gesture.html ), ale w mojej aplikacji nie używam Viewflippera. Gdy pojawia się przelotka, po prostu zmieniam zakładkę (owijając się w ends).

Teraz niektóre z moich zakładek zawierają przewijanie. Te przewijanie oczywiście reagują na przewijania w górę/w dół, aby umożliwić przeglądanie wszystkich danych w nim, nie ma niespodzianki. Problem polega na tym, że pojawi się funkcja "przewijania" tych przewijania nadpisuje mój gest przelotny. Nie mogę rzucać wewnątrz widoku przewijania (przewijać dobrze), ale działa bezbłędnie poza nimi(na tej samej karcie, na innych widokach, takich jak TableRow lub cokolwiek).

Rzuciłem okiem na http://blog.velir.com/index.php/2010/11/17/android-snapping-horizontal-scroll / too, który umożliwia implementację HorizontalScrollView. Ale nadal obsługuje gesty poprzez klasę, która rozszerza SimpleOnGestureListener( i nadpisuje onFling), która jest tą samą implementacją ,co ja (co prowadzi mnie do przekonania, że to naprawdę nie pomoże). Kod źródłowy dla ScrollView od Google: http://google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/widget/ScrollView.java&d=3

Czy Jest jakiś sposób, aby moja implementacja Swipe i ScrollView współpracowała bez wysiłku?

Chyba tu leży problem. ScrollView.java używa również metody o nazwie onTouchEvent i dokumentacji dla onTouchEvent dla Stanów aktywności:

"wywołane, gdy zdarzenie dotykowe było nie obsługiwane przez żadnego z widoków pod to. Jest to najbardziej przydatne do przetwarzania dotknij zdarzeń, które dzieją się poza TWOJE granice okien, gdzie nie ma zobacz, aby go otrzymać."

Więc ScrollView to "nadpisuje" - co mam zrobić? Czy nie ma sposobu, aby upewnić się, że oba są sprawdzone? Mój onTouchEvent, który nie jest trafiony, gdy onTouchEvent jest obsługiwany przez ScrollView:

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

Bardziej ogólny kod źródłowy poniżej, prawdopodobnie nie jest zbyt istotny. GestureDetector inside my Tabs class with its associated listener:

    // 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;
        }
    };

Moja klasa gest, która jest zagnieżdżoną klasą mojej klasy Tabs (która rozszerza TabActivity) - jest taka sama jak każdy inny kod, który znajdziesz na ten temat:

/** 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;
    }
}
Author: Community, 2011-02-24

3 answers

Proponuję spojrzeć na kod źródłowy aplikacji Google I/O 2010, ponieważ ich implementacja FlingableTabHost wydaje się rozwiązywać ten problem:

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

Myślę, że kluczem jest rozszerzenie TabHost i nadpisanie jej metody onInterceptTouchEvent.

 19
Author: Jeff Gilfelt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-06 11:48:54

Szukając rozwiązania podobnego problemu, który mam, natknąłem się na ten tid-bit:

EventsInterceptionEnabled: po ustawieniu na true, ta właściwość mówi nakładce, aby ukradła zdarzenia swoim dzieciom, gdy tylko dowie się, że użytkownik naprawdę rysuje gest. Jest to przydatne, gdy pod nakładką znajduje się przewijalny widok, aby uniknąć przewijania dziecka, gdy użytkownik rysuje swój gest]}

Ze strony Android Dev site , mówi o użyciu tego atrybut w katalogu głównym <android.gesture.GestureOverlayView> w pliku układu.

 0
Author: Kingsolmn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-17 18:00:34

Jeśli to coś warte, uważam, że metoda onflinga jest bardzo zawodna. Nadpisuję metodę onScroll w SimpleGestureDetector i definiuję mój onInterceptTouchEvent jako:

@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
Author: esilver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-01 04:29:35