He implementado SwipeRefreshLayout
y ViewPager
en mi aplicación, pero hay un gran problema: cada vez que voy a deslizar el dedo hacia la izquierda / derecha para cambiar entre páginas, el desplazamiento es demasiado sensible. Un pequeño deslizamiento hacia abajo también activará la SwipeRefreshLayout
actualización.
Quiero establecer un límite para cuando comience el deslizamiento horizontal, luego forzar horizontalmente solo hasta que termine el deslizamiento. En otras palabras, quiero cancelar el deslizamiento vertical cuando el dedo se mueve horizontalmente.
Este problema solo ocurre en ViewPager
, si deslizo hacia abajo y SwipeRefreshLayout
se activa la función de actualización (se muestra la barra) y luego muevo mi dedo horizontalmente, todavía solo permite deslizamientos verticales.
Intenté extender la ViewPager
clase pero no funciona en absoluto:
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean in = super.onInterceptTouchEvent(ev);
if (in) {
getParent().requestDisallowInterceptTouchEvent(true);
this.requestDisallowInterceptTouchEvent(true);
}
return false;
}
}
Diseño xml:
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/viewTopic"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.myapp.listloader.foundation.CustomViewPager
android:id="@+id/topicViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
Cualquier ayuda será apreciada, gracias
fuente
SwipeRefreshLayout
?Respuestas:
No estoy seguro de si todavía tiene este problema, pero la aplicación de E / S de Google iosched resuelve este problema de la siguiente manera:
Yo lo he usado igual y funciona bastante bien.
EDITAR: Use addOnPageChangeListener () en lugar de setOnPageChangeListener ().
fuente
Resuelto de manera muy simple sin extender nada
trabajar como un encanto
fuente
View
que pueda tener dentro delViewPager
, ya queSwipeRefreshLayout
permite incluso el desplazamiento vertical solo para su hijo de nivel superior (y en API inferiores a ICS solo si resulta ser unListView
) .ViewPager
dentroSwipeRefrestLayout
y ViewPager tieneListview
!SwipeRefreshLayout
déjame desplazarme hacia abajo pero al desplazarme hacia arriba se activa el progreso de actualización. ¿Cualquier sugerencia?He conocido tu problema. Personalizar SwipeRefreshLayout resolvería el problema.
Ver la referencia: enlace
fuente
Basé esto en una respuesta anterior, pero descubrí que esto funciona un poco mejor. El movimiento comienza con un evento ACTION_MOVE y termina en ACTION_UP o ACTION_CANCEL en mi experiencia.
fuente
Por alguna razón que solo ellos conocen, el equipo de desarrollo de la biblioteca de soporte consideró oportuno interceptar enérgicamente todos los eventos de movimiento de arrastre vertical del
SwipeRefreshLayout
diseño secundario, incluso cuando un niño solicita específicamente la propiedad del evento. Lo único que verifican es que el estado de desplazamiento vertical de su hijo principal esté en cero (en el caso de que su hijo sea desplazable verticalmente). ElrequestDisallowInterceptTouchEvent()
método se ha anulado con un cuerpo vacío y el comentario (no tan) esclarecedor "No".La forma más fácil de resolver este problema sería simplemente copiar la clase de la biblioteca de soporte en su proyecto y eliminar la anulación del método.
ViewGroup
La implementación de utiliza el estado interno para el manejoonInterceptTouchEvent()
, por lo que no puede simplemente anular el método nuevamente y duplicarlo. Si realmente desea anular la implementación de la biblioteca de soporte, entonces tendrá que configurar una marca personalizada en las llamadasrequestDisallowInterceptTouchEvent()
y anularonInterceptTouchEvent()
yonTouchEvent()
(o posiblemente piratearcanChildScrollUp()
) el comportamiento basado en eso.fuente
Encontré una solución para ViewPager2. Utilizo la reflexión para reducir la sensibilidad al arrastre de esta manera:
Funciona de maravilla para mí.
fuente
Hay un problema con la solución de nhasan:
Si el deslizamiento horizontal que desencadena la
setEnabled(false)
llamadaSwipeRefreshLayout
en elOnPageChangeListener
ocurre cuando elSwipeRefreshLayout
ya ha reconocido un Pull-to-Reload pero aún no ha llamado a la devolución de llamada de notificación, la animación desaparece, pero el estado interno deSwipeRefreshLayout
permanece en "refrescando" para siempre, ya que no Se llaman devoluciones de llamada de notificación que podrían restablecer el estado. Desde la perspectiva del usuario, esto significa que Pull-to-Reload ya no funciona porque no se reconocen todos los gestos de extracción.El problema aquí es que la
disable(false)
llamada elimina la animación de la ruleta y la devolución de llamada de notificación se llama desde elonAnimationEnd
método de un AnimationListener interno para esa ruleta que está desordenada de esa manera.Es cierto que nuestro probador, con los dedos más rápidos, provocó esta situación, pero también puede suceder de vez en cuando en escenarios realistas.
Una solución para solucionar esto es anular el
onInterceptTouchEvent
método de laSwipeRefreshLayout
siguiente manera:Use el
MySwipeRefreshLayout
en su Diseño - Archivo y cambie el código en la solución de mhasan afuente
Podría haber un problema con @huu duy answer cuando ViewPager se coloca en un contenedor de desplazamiento vertical que, a su vez, se coloca en SwiprRefreshLayout. Si el contenedor de contenido desplazable no se desplaza completamente hacia arriba, es posible que no sea posible activar deslizar para actualizar en el mismo gesto de desplazamiento hacia arriba. De hecho, cuando comienza a desplazarse por el contenedor interno y mueve el dedo horizontalmente más que mTouchSlop involuntariamente (que es 8dp por defecto), el CustomSwipeToRefresh propuesto rechaza este gesto. Por lo tanto, un usuario debe intentarlo una vez más para comenzar a actualizar. Esto puede parecer extraño para el usuario. Extraje el código fuente del SwipeRefreshLayout original de la biblioteca de soporte a mi proyecto y reescribí el onInterceptTouchEvent ().
Vea mi proyecto de ejemplo en Github .
fuente