2012-04-17 17 views
9

Tengo una ViewPager con algunas vistas. Me gustaría ir al primero después de deslizar el último derecho.¿Cómo hacer un bucle ViewPager?

me trataron

@Override 
public Fragment getItem(int arg0) { 
    int i = arg0 % fragmentList.size(); 
    return fragmentList.get(i); 
} 

@Override 
public int getCount() { 
    return fragmentList.size()+1; 
} 

pero me dio un error

E/AndroidRuntime(22912): java.lang.IllegalStateException: Fragment already added: RubricFragment{4136cd80 #1 id=0x7f06000c android:switcher:2131099660:0} 
+0

cheque esta http://stackoverflow.com/q/7546224/1263908 – sique

+0

http://stackoverflow.com/questions/7440012/infinite-viewpager – blessenm

Respuesta

5

me gustaría crear una página ficticia al final de la ViewPager. Luego uso este código para ir a la primera página cuando el usuario se desplaza a la página ficticia. Sé que es lejos de ser perfecto: D

@Override 
public void onPageScrolled(int position, float arg1, int arg2) { 
    if (position >= NUM_PAGE-1) { 
     mViewPager.setCurrentItem(0, true); 
    } 
} 
+0

si lo hace De esta manera, sí puede lograr un desplazamiento infinito, pero cuando se desplaza en la última página verá la animación como volver a scren1 .. –

24

Una posibilidad es la creación de las pantallas de la siguiente manera:

C 'ABCA'

C' se parece a C, pero cuando se desplaza hasta allí , que le pasa a la verdadera C. a' se parece a a, pero cuando se desplaza hasta allí, le cambia a la verdadera A.

me gustaría hacer esto mediante la implementación de onPageScrollStateChanged así:

@Override 
public void onPageScrollStateChanged (int state) { 
    if (state == ViewPager.SCROLL_STATE_IDLE) { 
     int curr = viewPager.getCurrentItem(); 
     int lastReal = viewPager.getAdapter().getCount() - 2; 
     if (curr == 0) { 
      viewPager.setCurrentItem(lastReal, false); 
     } else if (curr > lastReal) { 
      viewPager.setCurrentItem(1, false); 
     } 
    } 
} 

Tenga en cuenta que esto requiere la forma alternativa de setCurrentItem y pasa false para hacer que el salto a suceder al instante y no como un desplazamiento suave.

Hay dos inconvenientes principales que veo en esto. En primer lugar, al llegar a cualquiera de los extremos, el usuario tiene que dejar que el desplazamiento se asiente antes de que pueda avanzar. En segundo lugar, significa tener una segunda copia de todas las vistas en su primera y última página. Dependiendo de la carga de recursos de sus pantallas, puede descartar esta técnica como una posible solución.

Tenga en cuenta también que dado que el buscapersonas no permite que los clics pasen a los controles subyacentes hasta que se haya establecido el desplazamiento, es probable que no configure clicklisteners y similares para los fragmentos A 'y C'.

Editar: Ahora que lo he implementado, hay otro inconveniente bastante importante. Cuando cambia de A 'a A o C' a C, la pantalla parpadea por un momento, al menos en mi dispositivo de prueba actual.

+0

¡Excelente respuesta! ¡Lo usé y funciona perfecto! – vandzi

+0

Hola, ¿podrías encontrar una forma de evitar el parpadeo? – RMalke

+0

¡Solución increíble para mi tarea! Thx – mbelsky

0

esto debe hacer el trabajo sin páginas ficticias:

private boolean isFirstOrLastPage; 
private int currentPageIndex = 0; 


@Override 
public void onPageScrolled(int arg0, float arg1, int arg2) { 
    if(currentPageIndex!=arg0){ 
     isFirstOrLastPage = false; 
     return; 
    } 
    if((arg0==0 || arg0==PAGES.size()-1) && arg1 == 0 && arg2 == 0){ 
     if(isFirstOrLastPage){ 
       //DO SOMETHING 
     }else{ 
      isFirstOrLastPage = true; 
     } 
    } 
} 

@Override 
public void onPageSelected(int arg0) { 
    currentPageIndex = arg0; 
} 
0

esto funciona, la respuesta aceptada no es bueno porque hay un retraso cuando el bucle sucede:

@Override 
public int getCount() { 
    return Integer.MAX_VALUE; 
} 

@Override 
public CharSequence getPageTitle(int position) { 
    String title = mTitleList.get(position % mActualTitleListSize); 
    return title; 
} 

@Override 
public Object instantiateItem(ViewGroup container, int position) { 
    int virtualPosition = position % mActualTitleListSize; 
    return super.instantiateItem(container, virtualPosition); 
} 

@Override 
public void destroyItem(ViewGroup container, int position, Object object) { 
    int virtualPosition = position % mActualTitleListSize; 
    super.destroyItem(container, virtualPosition, object); 
} 

respuesta tomado de aquí: ViewPager as a circular queue/wrapping

1

Mi solución se basa en benkc, pero la primera y la última animación de desplazamiento de página están desactivadas, y cuando las páginas "se desplazan" a la página real, la animación de desplazamiento se habilita de nuevo, este esquema puede resolver el primer inconveniente.

pero mi resultado ViewPager.setCurrentItem(position, false) sigue teniendo animación de desplazamiento, por lo que implemento una animación demasiado rápida.

la animación desplazamiento rápido como este, no me importa el comentario sólo mi código no usaron estos métodos:

public class FixedSpeedScroller extends Scroller { 
    private int mDuration = 0; 

    public FixedSpeedScroller(Context context) { 
     super(context); 
    } 

    @Override 
    public void startScroll(int startX, int startY, int dx, int dy, int duration) { 
     super.startScroll(startX, startY, dx, dy, mDuration); 
    } 

    @Override 
    public void startScroll(int startX, int startY, int dx, int dy) { 
     super.startScroll(startX, startY, dx, dy, mDuration); 
    } 
} 

y utilizar este método para la actividad de ViewPager

private Scroller scroller; 
private void setViewPagerScroll(boolean instant) { 
    try { 
     Field mScroller = null; 
     mScroller = ViewPager.class.getDeclaredField("mScroller"); 
     mScroller.setAccessible(true); 
     if (scroller == null) { 
      scroller = (Scroller) mScroller.get(mViewPager); 
     } 
     FixedSpeedScroller fss = new FixedSpeedScroller(mViewPager.getContext()); 
     mScroller.set(mViewPager, instant ? fss : scroller); 

    } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { 
     e.printStackTrace(); 
    } 
} 

y modifique onPageScrollStateChanged como este, solo la primera página o la última página (tengo 5 páginas) cambiaría la animación a desplazamiento rápido, de lo contrario tiene un desplazamiento normal:

public void onPageScrollStateChanged(int state) { 
    if (state == ViewPager.SCROLL_STATE_IDLE) { 
     if (position == 0) { 
      setViewPagerScroll(true); 
      mViewPager.setCurrentItem(3); 

     } else if (position == 4) { 
      setViewPagerScroll(true); 
      mViewPager.setCurrentItem(1); 

     } else { 
      setViewPagerScroll(false); 
     } 
    } 
} 

referencias FixedSpeedScroller está aquí: http://blog.csdn.net/ekeuy/article/details/12841409

Cuestiones relacionadas