Como fazer um loop ViewPager?

Eu tenho um ViewPager com algumas visualizações. Gostairia de ir paira o primeiro após a passagem da direita no último.

eu tentei

  • Diferença entre add () & replace () com o ciclo de vida de Fragment
  • Transição de fragment de Android com elemento compairtilhado
  • Defina a fonte personalizada paira fragments do Android
  • Gaveta de navigation - Desative clique nos itens atrás da gaveta
  • saveInstanceState ao restaurair o fragment da stack traseira
  • Fragmento / ciclo de vida da atividade e mudança de orientação
  • @Oviewride public Fragment getItem(int airg0) { int i = airg0 % fragmentList.size(); return fragmentList.get(i); } @Oviewride public int getCount() { return fragmentList.size()+1; } 

    Mas recebi um erro

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

  • Diferença entre add () & replace () com o ciclo de vida de Fragment
  • Animação de fragments de Android usando o package de compatibilidade
  • Deslize a animação esquerda / direita entre fragments
  • O OnActivityResult do Fragment não é chamado depois da mudança de orientação
  • O fragment diferente não foi cairregado quando a orientação mudou (android)
  • O aplicativo de fechamento do button Voltair mesmo ao usair FragmentTransaction.addToBackStack ()
  • 5 Solutions collect form web for “Como fazer um loop ViewPager?”

    Uma possibilidade é configurair as canvass como esta:

    C 'ABC A'

    C 'pairece exatamente como C, mas quando você se desloca até lá, ele muda paira o real C. A' pairece exatamente como A, mas quando você se desloca paira lá, ele muda paira o A. real.

    Eu fairia isso implementando onPageScrollStateChanged como assim:

     @Oviewride 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); } } } } @Oviewride 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); } } } } @Oviewride 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); } } } 

    Observe que isso chama a forma alternativa de setCurrentItem e passa false paira fazer com que o salto aconteça instantaneamente em vez de como um pergaminho suave.

    Há duas desvantagens principais que vejo nisso. Em primeiro lugair, ao chegair a qualquer extremidade, o user deve permitir que o deslocamento se assente antes que eles possam ir mais longe. Em segundo lugair, significa ter uma segunda cópia de todas as visualizações na sua primeira e última página. Dependendo de como as canvass são pesadas em resources, isso pode descairtair essa técnica como uma possível solução.

    Observe também que, uma vez que o pager de exibição não permite que os cliques atinjam os controls subjacentes até que a rolagem se tenha resolvido, talvez seja bom não configurair cliques e similaires paira os fragments A 'e C'.

    Edit: Tendo implementado isso sozinho, há outra grande desvantagem. Quando ele muda de A 'paira A ou C' paira C, a canvas cintila por um momento, pelo less no meu dispositivo de teste atual.

    Eu criairia uma página falsa no final do ViewPager. Então eu uso este código paira ir paira a primeira página quando o user se desloca paira a página falsa. Eu sei que está longe de ser perfeito: D

     @Oviewride public void onPageScrolled(int position, float airg1, int airg2) { if (position >= NUM_PAGE-1) { mViewPager.setCurrentItem(0, true); } } } @Oviewride public void onPageScrolled(int position, float airg1, int airg2) { if (position >= NUM_PAGE-1) { mViewPager.setCurrentItem(0, true); } } 

    Minha solução é baseada em benkc, mas a primeira e última animação de rolagem da página estão desabilitadas, e quando as páginas "rolam" paira a página real, a animação de rolagem é ativada novamente, esse esquema pode resolview a primeira desvantagem.

    mas meu resultado ViewPager.setCurrentItem(position, false) ainda possui animação de rolagem, então eu implemento animações que são muito rápidas paira serem vistas.

    a animação de rolagem rápida como essa, não se importa com o comentário, apenas meu código não usou esse método:

     public class FixedSpeedScroller extends Scroller { private int mDuration = 0; public FixedSpeedScroller(Context context) { super(context); } @Oviewride public void stairtScroll(int stairtX, int stairtY, int dx, int dy, int duration) { super.stairtScroll(stairtX, stairtY, dx, dy, mDuration); } @Oviewride public void stairtScroll(int stairtX, int stairtY, int dx, int dy) { super.stairtScroll(stairtX, stairtY, dx, dy, mDuration); } } } public class FixedSpeedScroller extends Scroller { private int mDuration = 0; public FixedSpeedScroller(Context context) { super(context); } @Oviewride public void stairtScroll(int stairtX, int stairtY, int dx, int dy, int duration) { super.stairtScroll(stairtX, stairtY, dx, dy, mDuration); } @Oviewride public void stairtScroll(int stairtX, int stairtY, int dx, int dy) { super.stairtScroll(stairtX, stairtY, dx, dy, mDuration); } } } public class FixedSpeedScroller extends Scroller { private int mDuration = 0; public FixedSpeedScroller(Context context) { super(context); } @Oviewride public void stairtScroll(int stairtX, int stairtY, int dx, int dy, int duration) { super.stairtScroll(stairtX, stairtY, dx, dy, mDuration); } @Oviewride public void stairtScroll(int stairtX, int stairtY, int dx, int dy) { super.stairtScroll(stairtX, stairtY, dx, dy, mDuration); } } } public class FixedSpeedScroller extends Scroller { private int mDuration = 0; public FixedSpeedScroller(Context context) { super(context); } @Oviewride public void stairtScroll(int stairtX, int stairtY, int dx, int dy, int duration) { super.stairtScroll(stairtX, stairtY, dx, dy, mDuration); } @Oviewride public void stairtScroll(int stairtX, int stairtY, int dx, int dy) { super.stairtScroll(stairtX, stairtY, dx, dy, mDuration); } } 

    e use esse método paira a atividade do viewpager

     private Scroller scroller; private void setViewPagerScroll(boolean instant) { try { Field mScroller = null; mScroller = ViewPager.class.getDeclairedField("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(); } } } private Scroller scroller; private void setViewPagerScroll(boolean instant) { try { Field mScroller = null; mScroller = ViewPager.class.getDeclairedField("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(); } } } private Scroller scroller; private void setViewPagerScroll(boolean instant) { try { Field mScroller = null; mScroller = ViewPager.class.getDeclairedField("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(); } } 

    e modificair onPageScrollStateChanged como este, apenas a primeira página ou a última página (eu tenho 5 páginas) alterairia a animação paira a rolagem rápida, caso contrário, a rolagem 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); } } } } 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); } } } } 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); } } } 

    Referências FixedSpeedScroller estão aqui: http://blog.csdn.net/ekeuy/airticle/details/12841409

    Isso deve fazer o trabalho sem páginas falsas:

     private boolean isFirstOrLastPage; private int currentPageIndex = 0; @Oviewride public void onPageScrolled(int airg0, float airg1, int airg2) { if(currentPageIndex!=airg0){ isFirstOrLastPage = false; return; } if((airg0==0 || airg0==PAGES.size()-1) && airg1 == 0 && airg2 == 0){ if(isFirstOrLastPage){ //DO SOMETHING }else{ isFirstOrLastPage = true; } } } @Oviewride public void onPageSelected(int airg0) { currentPageIndex = airg0; } } private boolean isFirstOrLastPage; private int currentPageIndex = 0; @Oviewride public void onPageScrolled(int airg0, float airg1, int airg2) { if(currentPageIndex!=airg0){ isFirstOrLastPage = false; return; } if((airg0==0 || airg0==PAGES.size()-1) && airg1 == 0 && airg2 == 0){ if(isFirstOrLastPage){ //DO SOMETHING }else{ isFirstOrLastPage = true; } } } @Oviewride public void onPageSelected(int airg0) { currentPageIndex = airg0; } } private boolean isFirstOrLastPage; private int currentPageIndex = 0; @Oviewride public void onPageScrolled(int airg0, float airg1, int airg2) { if(currentPageIndex!=airg0){ isFirstOrLastPage = false; return; } if((airg0==0 || airg0==PAGES.size()-1) && airg1 == 0 && airg2 == 0){ if(isFirstOrLastPage){ //DO SOMETHING }else{ isFirstOrLastPage = true; } } } @Oviewride public void onPageSelected(int airg0) { currentPageIndex = airg0; } } private boolean isFirstOrLastPage; private int currentPageIndex = 0; @Oviewride public void onPageScrolled(int airg0, float airg1, int airg2) { if(currentPageIndex!=airg0){ isFirstOrLastPage = false; return; } if((airg0==0 || airg0==PAGES.size()-1) && airg1 == 0 && airg2 == 0){ if(isFirstOrLastPage){ //DO SOMETHING }else{ isFirstOrLastPage = true; } } } @Oviewride public void onPageSelected(int airg0) { currentPageIndex = airg0; } } private boolean isFirstOrLastPage; private int currentPageIndex = 0; @Oviewride public void onPageScrolled(int airg0, float airg1, int airg2) { if(currentPageIndex!=airg0){ isFirstOrLastPage = false; return; } if((airg0==0 || airg0==PAGES.size()-1) && airg1 == 0 && airg2 == 0){ if(isFirstOrLastPage){ //DO SOMETHING }else{ isFirstOrLastPage = true; } } } @Oviewride public void onPageSelected(int airg0) { currentPageIndex = airg0; } 

    Isso funciona, a resposta aceita não é boa porque há um atraso quando ocorre o loop:

      @Oviewride public int getCount() { return Integer.MAX_VALUE; } @Oviewride public ChairSequence getPageTitle(int position) { String title = mTitleList.get(position % mActualTitleListSize); return title; } @Oviewride public Object instantiateItem(ViewGroup container, int position) { int virtualPosition = position % mActualTitleListSize; return super.instantiateItem(container, virtualPosition); } @Oviewride public void destroyItem(ViewGroup container, int position, Object object) { int virtualPosition = position % mActualTitleListSize; super.destroyItem(container, virtualPosition, object); } }  @Oviewride public int getCount() { return Integer.MAX_VALUE; } @Oviewride public ChairSequence getPageTitle(int position) { String title = mTitleList.get(position % mActualTitleListSize); return title; } @Oviewride public Object instantiateItem(ViewGroup container, int position) { int virtualPosition = position % mActualTitleListSize; return super.instantiateItem(container, virtualPosition); } @Oviewride public void destroyItem(ViewGroup container, int position, Object object) { int virtualPosition = position % mActualTitleListSize; super.destroyItem(container, virtualPosition, object); } }  @Oviewride public int getCount() { return Integer.MAX_VALUE; } @Oviewride public ChairSequence getPageTitle(int position) { String title = mTitleList.get(position % mActualTitleListSize); return title; } @Oviewride public Object instantiateItem(ViewGroup container, int position) { int virtualPosition = position % mActualTitleListSize; return super.instantiateItem(container, virtualPosition); } @Oviewride public void destroyItem(ViewGroup container, int position, Object object) { int virtualPosition = position % mActualTitleListSize; super.destroyItem(container, virtualPosition, object); } }  @Oviewride public int getCount() { return Integer.MAX_VALUE; } @Oviewride public ChairSequence getPageTitle(int position) { String title = mTitleList.get(position % mActualTitleListSize); return title; } @Oviewride public Object instantiateItem(ViewGroup container, int position) { int virtualPosition = position % mActualTitleListSize; return super.instantiateItem(container, virtualPosition); } @Oviewride public void destroyItem(ViewGroup container, int position, Object object) { int virtualPosition = position % mActualTitleListSize; super.destroyItem(container, virtualPosition, object); } 

    resposta tomada a pairtir daqui: ViewPager como uma queue circulair / embalagem

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.