¿Hay alguna forma de reducir la velocidad de desplazamiento con el adaptador de visor en Android?
Sabes, he estado mirando este código. No puedo entender qué estoy haciendo mal.
try{
Field mScroller = mPager.getClass().getDeclaredField("mScroller");
mScroller.setAccessible(true);
Scroller scroll = new Scroller(cxt);
Field scrollDuration = scroll.getClass().getDeclaredField("mDuration");
scrollDuration.setAccessible(true);
scrollDuration.set(scroll, 1000);
mScroller.set(mPager, scroll);
}catch (Exception e){
Toast.makeText(cxt, "something happened", Toast.LENGTH_LONG).show();
}
¿No cambia nada pero no se producen excepciones?
child.setNestedScrollingEnabled(false);
trabajó para míRespuestas:
Comencé con el código de HighFlyer que de hecho cambió el campo mScroller (que es un gran comienzo) pero no ayudó a extender la duración del desplazamiento porque ViewPager pasa explícitamente la duración al mScroller al solicitar el desplazamiento.
La extensión de ViewPager no funcionó porque el método importante (smoothScrollTo) no se puede anular.
Terminé arreglando esto extendiendo Scroller con este código:
Y usándolo así:
Básicamente, codifiqué la duración en 5 segundos e hice que mi ViewPager la usara.
Espero que esto ayude.
fuente
scroller.setFixedDuration(5000);
da un error? Dice "El método setFixedDuration (int) no está definido"Quería hacerlo yo mismo y he logrado una solución (sin embargo, usando la reflexión). Es similar a la solución aceptada, pero utiliza el mismo interpolador y solo cambia la duración según un factor. Necesita usar un
ViewPagerCustomDuration
en su XML en lugar deViewPager
, y luego puede hacer esto:ViewPagerCustomDuration.java
:ScrollerCustomDuration.java
:¡Espero que esto ayude a alguien!
fuente
Encontré una mejor solución, basada en la respuesta de @ df778899 y la API ValueAnimator de Android . Funciona bien sin reflejos y es muy flexible. Además, no es necesario crear ViewPager personalizado y ponerlo en el paquete android.support.v4.view. Aquí hay un ejemplo:
fuente
startFakeDrag
yendFakeDrag
que están destinados a hacer más de lo que está disponibleViewPager
de fábrica. Esto funciona muy bien para mí y es exactamente lo que estaba buscandoanimatePagerTransition(final boolean forward
método? Eso es lo que me confunde. ¿Lo llama en uno de losViewPager.OnPageChangeListener
métodos de interfaz? ¿O en otro sitio?Como puede ver en las fuentes de ViewPager, la duración de la aventura controlada por el objeto mScroller. En la documentación podemos leer:
Entonces, si desea controlar la velocidad, puede cambiar el objeto mScroller a través de la reflexión.
Deberías escribir algo como esto:
fuente
Esta no es la solución perfecta, no puede hacer que la velocidad sea más lenta porque es un
int
. Pero para mí es lo suficientemente lento y no tengo que usar la reflexión.Observe el paquete donde está la clase.
smoothScrollTo
tiene visibilidad de paquete.fuente
Notice the package where the class is
.package-local
fields
/methods
, si solo hace que Android Studio crea que está usando el mismo paquete. ¿Soy el único que huele un pocosealing violation
?Los métodos fakeDrag en ViewPager parecen proporcionar una solución alternativa.
Por ejemplo, esto pasará del elemento 0 al 1:
(El
count * count
está ahí para hacer que el arrastre se acelere a medida que avanza)fuente
He usado
Aquí está el ejemplo:
fuente
Según la solución aceptada, he creado la clase kotlin con extensión para el paginador de vista. ¡Disfrutar! :)
fuente
Aquí hay una respuesta que utiliza un enfoque completamente diferente. Alguien podría decir que esto tiene una sensación de hacky; sin embargo, no utiliza la reflexión y yo diría que siempre funcionará.
Encontramos el siguiente código en su interior
ViewPager.smoothScrollTo
:Calcula la duración basándose en algunas cosas. ¿Ves algo que podamos controlar?
mAdapter.getPageWidth
. Implementemos ViewPager.OnPageChangeListener en nuestro adaptador . Vamos a detectar cuando ViewPager se está desplazando y daremos un valor falso para el ancho . Si quiero que la duración seak*100
, entonces voy a volver1.0/(k-1)
agetPageWidth
. Lo siguiente es Kotlin impl de esta parte del adaptador que convierte la duración en 400:No olvide agregar el adaptador como OnPageChangedListener.
Mi caso particular puede asumir con seguridad que el usuario no puede deslizar para arrastrar entre páginas. Si tiene que soportar el asentamiento después de un arrastre, entonces necesita hacer un poco más en su cálculo.
Una desventaja es que esto depende de ese
100
valor de duración base codificado en ViewPager. Si eso cambia, entonces sus duraciones cambian con este enfoque.fuente
Quería resolver el mismo problema que todos ustedes y esta es mi solución para el mismo problema, pero creo que de esta manera la solución es más flexible ya que puede cambiar la duración como desee y también cambiar la interpolación de los valores como desee. para lograr diferentes efectos visuales. Mi solución pasa de la página "1" a la página "2", por lo que solo en posiciones crecientes, pero se puede cambiar fácilmente para ir en posiciones decrecientes haciendo "animProgress - lastFakeDrag" en lugar de "lastFakeDrag - animProgress". Creo que esta es la solución más flexible para realizar esta tarea.
fuente