android - recyclerview - Swipe/Fling cambiar la pestaña en conjunto con ScrollView?
swipe to refresh android (3)
Al buscar resolver un problema similar que tengo, encontré este tid-bit:
eventsInterceptionEnabled: cuando se establece en true, esta propiedad le dice a la superposición que robe los eventos de sus hijos tan pronto como sepa que el usuario realmente está dibujando un gesto. Esto es útil cuando hay una vista desplazable debajo de la superposición, para evitar desplazar al niño subyacente mientras el usuario dibuja su gesto.
Desde el sitio de desarrollo de Android , habla sobre el uso de este atributo en la raíz <android.gesture.GestureOverlayView>
en su archivo de diseño.
Lo mejor que pude encontrar sobre este tema en particular (aunque no uso una Galería): ScrollView y Galería interfieren , aunque en realidad no dan una respuesta específica. Y mi implementación no usa una galería, obviamente.
Salta a la siguiente parte en negrita para la parte interesante
Así que tengo Fling / Swipe / Flick / como quieras llamar para que funcione hace un tiempo en mi aplicación. La inspiración se obtuvo de un par de lugares diferentes, algunos de los cuales son "detección de gestos básicos" aquí en Stack Overflow ( Detección de gestos Fling en diseño de cuadrícula ), Code Shogun ( http://www.codeshogun.com/blog/2009/04/16/how-to-implement-swipe-action-in-android/ ) y Developing Android ( http://developingandroid.blogspot.com/2009/09/implementing-swipe-gesture.html ), pero no uso un ViewFlipper en mi aplicación. Cuando ocurre un lanzamiento, simplemente cambio la pestaña (envolviéndome por los extremos).
Ahora, algunas de mis pestañas contienen ScrollViews. Estos ScrollViews obviamente responden a los desplazamientos hacia arriba / hacia abajo para permitirle ver todos los datos que contiene, sin sorpresa alguna. El problema es que aparecería la función de "desplazamiento" de estas ScrollViews que sobrescriben mi gesto de lanzamiento. No puedo lanzar dentro de un ScrollView (desplazarse bien), pero funciona perfectamente fuera de ellos (en la misma pestaña, en otras vistas como TableRow o lo que sea).
También eché un vistazo rápido a http://blog.velir.com/index.php/2010/11/17/android-snapping-horizontal-scroll/ , que proporciona una manera de implementar HorizontalScrollView. Pero aún maneja los gestos a través de una clase que extiende SimpleOnGestureListener (y sobreescribe enFling), que es la misma implementación que tengo (lo que me lleva a creer que realmente no ayudará). Código fuente para ScrollView de Google: http://google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/widget/ScrollView.java&d=3
¿Hay alguna manera de hacer que mi implementación de Swipe y ScrollView trabajen juntas sin esfuerzo?
Aquí es donde radica el problema, supongo. ScrollView.java también usa un método llamado onTouchEvent y la documentación para los estados onTouchEvent for Activity:
"Llamado cuando un evento de pantalla táctil no fue manejado por ninguna de las vistas debajo de él. Esto es más útil para procesar eventos táctiles que ocurren fuera de los límites de la ventana, donde no hay vista para recibirlo".
Así que el ScrollView lo "anula", ¿qué hago? ¿No hay manera de asegurarse de que ambos están marcados? Mi onTouchEvent que no se ve afectado cuando el OnTouchEvent es manejado por ScrollView:
@Override
/** Used for swipe gestures */
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event))
return true;
else
return false;
}
Código fuente más general a continuación, probablemente no sea muy vital. El gestor de detección dentro de mi clase de pestañas con su oyente asociado:
// 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;
}
};
Mi clase de gestos, que es una clase anidada de mi clase de pestañas (que amplía TabActivity), es lo mismo que cualquier otro código que encontrará sobre este tema:
/** 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;
}
}
Le sugiero que eche un vistazo al código fuente de la aplicación Google I / O 2010, ya que su implementación FlingableTabHost
parece haber resuelto este problema:
http://iosched.googlecode.com/svn/trunk/src/com/google/android/apps/iosched/ui/ScheduleActivity.java
Creo que la clave está en extender TabHost
y anular su método onInterceptTouchEvent
.
Para lo que vale la pena, encontré el método onFling muy poco fiable. Anulo el método onScroll en SimpleGestureDetector y defino mi onInterceptTouchEvent como:
@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;
}