2012-08-17 13 views
13

Utilizo un PagerAdapter. Tengo muchos elementos, así que no cargo todos los elementos al mismo tiempo. Recargo el adaptador, cambio los elementos viejos por los nuevos elementos. Por ejemplo, tengo 4 elementos, cuando llego al último elemento, vuelvo a cargar los elementos y llamo a setCurentItem (1) para poder mostrar el viewpager en la posición uno. He hecho muchas pruebas. Puedo poner:setCurrentItem en ViewPager no desplazarse inmediatamente en la posición correcta

viewPager.setCurrentItem(1,false); //But not scroll, put drastically the new page. 
viewPager.setCurrentItem(1); 

He intentado modificar onPageScrollStateChanged (int arg0), solo tengo 3 puntos de vista y siempre UBÍCATE en el medio.

if (arg0 == ViewPager.SCROLL_STATE_DRAGGING) { 
    if(focusedPage==2) { 
     //Modify adapter 
     viewPager.setCurrentItem(1,false); 

    }else if(focusedPage==0){ 
     //Modify adapter 
     viewPager.setCurrentItem(1,false); 
    } 

Y he tryed para modificar onPageSelected (int arg0)

focusedPage=arg0; 

El uso de este último ejemplo tengo desplazarse los puntos de vista de inmediato, pero siempre se encuentra en la última página. Alguien sabe cómo puedo deslizarme.

Gracias

Respuesta

43

puedo saber más sobre el fondo de lo que está tratando de lograr?

De todos modos, por lo que puedo entender, estás tratando de hacer un "infinito" ViewPager yendo del último al primero y viceversa (corrígeme si me equivoco). Y desea que su ViewPager vaya a la primera página pero se desplace, no solo aparece de la nada.

Bueno, si desactiva el desplazamiento suave (el segundo parámetro), irá directamente a la página que desee sin movimiento de desplazamiento (y no "cambiará" a las otras páginas en el camino), y si habilitas el desplazamiento suave, luego pasará por todas las vistas, por lo que verás que no fue el siguiente sino el primero.

/*No swipe animation, and no onPageChanged for the page in the middle*/ 
    mPager.setCurrentItem(1, false); 

    /*The same as if you do not add the second parameter*/ 
    mPager.setCurrentItem(1, true); 

    /*Your ViewPager scrolls through all the needed views until it arrives at that view.*/ 
    mPager.setCurrentItem(1); 

Lo que puedo recomendar a usted con esto en mente es que se puede tratar de añadir la vista "de prueba" en las posiciones 0 y "último" y la vista en la posición 0 sería la misma que la posición "última - 1 "y la" última "vista sería la misma que la posición" 1 ". Por lo tanto, hará todo lo normal, EXCEPTO que en OnPageChangeListener comprobará si la página actual es la posición "0" o "última" y, en caso afirmativo, llamará a setCurrentItem ("1", false) o setCurrentItem ("last - 1 ", falso) dependiendo de la posición en la que se encuentre ahora. De esta forma, mantendrá el efecto de "cambio de página" mientras logra lo que desea.

Espero que esto pueda ayudarlo con su problema.

NOTA: que puede tener un cambio lag después de su llegada en la nueva posición, ya que tendrá que cargar la vista de la visión actual, próxima y última (o si está en 4.0+ entonces será cargar solo la posición real).

ACTUALIZACIÓN:

Si cambia el contenido de la Lista/matriz que determina el contenido de la ViewPager, tiene que llamar:

ViewPager mPager = new ViewPager(); 
mPager.getAdapter().notifyDataSetChanged(); //This notify that you need to recreate the views 

/*This is if you want to change the data and then go to a specific position 
If you do not do this you will have a very Buggy Behavior*/ 
new Handler().post(new Runnable() { 
@Override 
public void run() { 
    mPager.setCurrentItem(2); //Where "2" is the position you want to go 
    } 
}); 

ACTUALIZACIÓN 2:

¿Por qué no agrega todos sus elementos al ViewPager? el ViewPager ya tiene la optimización para manejar esos casos, en mi caso tengo muchos elementos y funciona como un hechizo.

Otra cosa, en su código veo que cambia a la página del medio cada vez que una página se "establece". Pero en realidad nunca muestra la vista derecha e izquierda, entonces, ¿por qué las tiene?

Por último, cuando cambia su conjunto de datos, necesita llamar al método "notifyDataSetChanged" que mencioné anteriormente, y luego llama al método "setCurrentItem" dentro de un manejador. Si no lo hace, su aplicación no funcionará como se esperaba.

Actualización 3:

Bueno, lo único que puedo recomendar es tener una lista en la que seguir añadiendo los nuevos objetos que traen de la base de datos y, a continuación, siempre y cuando mantenga insertar objetos a la al final de la lista no hay problema. Si desea agregar objetos en el medio o al principio, debe llamar a notifyDataSetChanged, pero va a ser un poco lento porque generará las vistas nuevamente. Lo hacemos de esta manera y funciona perfectamente e incluso descargamos la información de un servidor, los datos no son locales (y de hecho agregamos información al final y al comienzo de la Lista).

Si tiene alguna otra pregunta sobre cómo lograr esto, no dude en preguntar.

ACTUALIZACIÓN 4:

Sólo en caso de que alguien está buscando realmente una circular ViewPager, he añadido un proof of concept code que se puede reutilizar. Funciona sin problemas y lo he usado con vistas complejas y todavía no hay retraso alguno.

+0

Gracias @Jorge Aguilar. He usado tu idea, pero he cambiado algunas cosas. He agregado una vista "ficticia" pero he puesto diferentes vistas. Por ejemplo, si tengo a, b, c, d, e. He puesto la primera vez: a, a, a. Y setCurrentItem (1, falso). Cuando el usuario se desplaza al siguiente viewpager, es: a, b, c y setCurrentItem (1, falso), ... En onPageScrollStateChanged he puesto este código. Pero ahora tengo un pequeño problema. Si el usuario desea desplazarse rápidamente, no puede porque hay demoras. ¿Tiene alguna idea? Gracias – MARM

+0

¿Puede editar su pregunta o publicar una nueva pregunta con más detalles sobre el nuevo problema para comprenderlo mejor y ayudarlo mejor? Ya actualicé la respuesta para agregar algunas cosas valiosas. Y si puede marcar esto como respuesta para cualquier persona que ingrese, puede saber que fue resuelto. –

+0

He editado mi pregunta. – MARM

1

No funciona sin postDelayed, tratar con este código:

viewPager.postDelayed(new Runnable() 
{ 
    @Override 
    public void run() 
    { 
     viewPager.setCurrentItem(num, true); 
    } 
}, 100); 
Cuestiones relacionadas