Infinite Scrolling Image ViewPager

Según lo documentado por Google, la clase Gallery quedó en desuso en el nivel 16 de la API. Este widget ya no es compatible. Otros widgets de desplazamiento horizontal incluyen HorizontalScrollView y ViewPager de la biblioteca de soporte. Así que utilicé ViewPager como una alternativa a la clase Gallery.

Mi objective es finalmente lograr una imagen infinita de desplazamiento ViewPager con descripciones de texto . Utilicé el siguiente código para obtener la imagen ViewPager con texto que describe cada imagen, pero ¿cómo aplico Infinite Scrolling a ViewPager?

No he trabajado con ViewPager antes, así que intente proporcionar un código detallado si es posible.

activity_main.xml:

   

custom_pager.xml:

     

ImagePager:

 public class ImagePager extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImagePagerAdapter adapter = new ImagePagerAdapter(this, imageArra, stringArray ); ViewPager myPager = (ViewPager) findViewById(R.id.myimagepager); myPager.setAdapter(adapter); myPager.setCurrentItem(0); } private int imageArra[] = { R.drawable.a, R.drawable.b,R.drawable.c, R.drawable.d,R.drawable.e,R.drawable.f, R.drawable.g, R.drawable.h, R.drawable.i}; private String[] stringArray = new String[] { "Image a", "Image b","Image c" "Image d","Image e","Image f", "Image g","Image h","Image i"}; } 

ImagePagerAdapter:

 public class ImagePagerAdapter extends PagerAdapter { Activity activity; int imageArray[]; String[] stringArray; public ImagePagerAdapter(Activity act, int[] imgArra, String[] stringArra) { imageArray = imgArra; activity = act; stringArray = stringArra; } public int getCount() { return imageArray.length; } public Object instantiateItem(View collection, int position) { LayoutInflater inflater = (LayoutInflater)collection.getContext ().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View layout = inflater.inflate(R.layout.custom_pager, null); ImageView im=(ImageView) layout.findViewById(R.id.myimage); im.setImageResource(imageArray[position]); TextView txt=(TextView) layout.findViewById(R.id.image_text); txt.setText(stringArray[position]); ((ViewPager) collection).addView(layout, 0); return layout; } @Override public void destroyItem(View arg0, int arg1, Object arg2) { ((ViewPager) arg0).removeView((View) arg2); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == ((View) arg1); } @Override public Parcelable saveState() { return null; } } 

Tuve el mismo problema , pero pude encontrar una manera de resolverlo; el código se puede encontrar en github .

Si copia las clases InfiniteViewPager e InfinitePagerAdapter en su proyecto, puede lograr un desplazamiento infinito (envuelto) con algunos pequeños cambios.

En su actividad, ajuste su PagerAdapter con InfinitePagerAdapter :

 PagerAdapter adapter = new InfinitePagerAdapter(new ImagePagerAdapter(this, imageArra, stringArray)); 

Cambia la ViewPager en el XML de actividad para ser un InfiniteViewPager :

  

Puedes cambiar el nombre de las clases a lo que quieras. Este código solo funciona si tiene al menos tres páginas (tiene nueve en su código de ejemplo, por lo que funcionará bien para eso).

Ya encontré la manera de hacer un truco simple, espero que te ayude

 import java.util.ArrayList; import android.os.Bundle; import android.app.Activity; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.Log; public class ImagePager extends Activity { String[] stringArray; int[] imageArra; ViewPager myPager; Boolean isScrooled = false; // use this array yo understand swipe left or right ? ArrayList pos = new ArrayList(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // put empty view at the beginnig and to end imageArra = new int[] { 0, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, 0 }; // put empty string at the beginnig and to end stringArray = new String[] { "", "Image a", "Image b", "Image c", "Image d", "Image e", "Image f", "Image g", "Image h", "Image i", "" }; ImagePagerAdapter adapter = new ImagePagerAdapter(this, imageArra, stringArray); myPager = (ViewPager) findViewById(R.id.myimagepager); myPager.setAdapter(adapter); myPager.setCurrentItem(1); myPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int arg0) { Log.v("onPageSelected", String.valueOf(arg0)); pos.clear(); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { try { // while scrolling i add ever pos to array pos.add(arg1); // if pos.get(0) > pos.get(pos.size() - 1) // <----- swipe <----- // we should check isScroll because setCurrent item is not a croll ? if (pos.size() > 0) if (arg0 == imageArra.length - 1 & pos.get(0) > pos.get(pos.size() - 1) & isScrooled == true) { try { isScrooled = false; myPager.setCurrentItem(1, false); } catch (Exception e) { Log.v("hata", "<----- swipe <----- " + e.toString()); } } // ----> swipe ----> else if (arg0 == 0 & pos.get(0) < pos.get(pos.size() - 1) & isScrooled == true) { try { isScrooled = false; myPager.setCurrentItem(imageArra.length - 1, false); } catch (Exception e) { Log.v("hata", "----> swipe ----> " + e.toString()); } } else if (arg0 == 0 & pos.size() == 1 & isScrooled == true) { try { isScrooled = false; myPager.setCurrentItem(imageArra.length - 1, false); } catch (Exception e) { Log.v("hata", "----> swipe ----> " + e.toString()); } } } catch (Exception e) { Log.v("hata", e.toString()); } } @Override public void onPageScrollStateChanged(int arg0) { Log.v("onPageScrollStateChanged", String.valueOf(arg0)); // set is scrolling isScrooled = true; } }); } } 

[EDIT 1]

 import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.Log; public class ImagePager extends Activity { String[] stringArray; int[] imageArra; ViewPager myPager; int scrollState; Boolean isFirstVisitEnd= true,isFirstVisitBegin = true; ArrayList pos = new ArrayList(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageArra = new int[] { 0,R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, 0 }; stringArray = new String[] {"","Image a", "Image b", "Image c", "Image d", "Image e", "Image f", "Image g", "Image h", "Image i", "" }; ImagePagerAdapter adapter = new ImagePagerAdapter(this, imageArra, stringArray); myPager = (ViewPager) findViewById(R.id.myimagepager); myPager.setAdapter(adapter); myPager.setCurrentItem(1); myPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int arg0) { Log.v("onPageSelected", String.valueOf(arg0)); pos.clear(); if (arg0 == imageArra.length - 1) isFirstVisitEnd = false; else isFirstVisitEnd = true; if (arg0 == 0) isFirstVisitBegin = false; else isFirstVisitBegin = true; } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { try { pos.add(Integer.valueOf(arg2)); if (pos.size() > 0) { //Log.v("onPageScrolled_arg2","arg0 : "+String.valueOf(arg0)+" ilk : "+pos.get(0).toString()+" son : " +pos.get(pos.size() - 1).toString()+ " "+ String.valueOf(pos.get(0)-(pos.get(pos.size() - 1)))+" isFirstVisitEnd: "+String.valueOf(isFirstVisitEnd.booleanValue()) ); // <----- swipe <----- if (arg0 == imageArra.length - 2& (pos.get(pos.size() - 1) -pos.get(0) < 100)& scrollState == 2 & isFirstVisitEnd == false) { myPager.setCurrentItem(1, false); } //Log.v("onPageScrolled_arg2","arg0 : "+String.valueOf(arg0)+" ilk : "+pos.get(0).toString()+" son : " +pos.get(pos.size() - 1).toString()+ " "+ String.valueOf(pos.get(0)-(pos.get(pos.size() - 1)))+" isFirstVisitbegin: "+String.valueOf(isFirstVisitBegin.booleanValue()) ); if (arg0 == 0 & (pos.get(pos.size() - 1) -pos.get(0) > -100)& scrollState == 2 & isFirstVisitBegin == false) { myPager.setCurrentItem(imageArra.length - 2, false); } } } catch (Exception e) { Log.v("hata", e.toString()); } } @Override public void onPageScrollStateChanged(int arg0) { Log.v("onPageScrollStateChanged", String.valueOf(arg0)); scrollState =arg0; } }); } } 

Creo que mi solución es más simple.

Atención a mi matriz de estructura de imágenes:

 Item 0 => last image Item count()-1 => first image 

El truco está en onPageScrollStateChanged :

Cuando el usuario se desplaza al último elemento -> el buscapersonas salta sin animación a la primera imagen (posición = 1)

Cuando el usuario se desplaza al primer elemento -> el buscapersonas salta sin animación a la última imagen (posición = conteo – 2)

 public class InfiniteScrollingActivity extends ActionBarActivity { private ViewPager pager; private MyAdapter adapter; int[] promoImageIds = new int[]{R.drawable.cover6, R.drawable.cover1, R.drawable.cover2, R.drawable.cover3, R.drawable.cover4, R.drawable.cover5, R.drawable.cover6, R.drawable.cover1 }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_test); adapter = new MyAdapter(getSupportFragmentManager(), promoImageIds); pager = (ViewPager)findViewById(R.id.pager); pager.setAdapter(adapter); pager.setCurrentItem( 1 ); pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int index) { Log.v( "onPageSelected", String.valueOf( index ) ); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { // Log.v("onPageScrolled", ""); } @Override public void onPageScrollStateChanged(int state) { Log.v("onPageScrollStateChanged", String.valueOf(state)); if (state ==ViewPager.SCROLL_STATE_IDLE) { int index = pager.getCurrentItem(); if ( index == 0 ) pager.setCurrentItem( adapter.getCount() - 2, false ); else if ( index == adapter.getCount() - 1 ) pager.setCurrentItem( 1 , false); } } }); } public static class MyAdapter extends FragmentPagerAdapter { int[] promoImageIds; public MyAdapter(FragmentManager fm, int[] promoImageIds){ super(fm); this.promoImageIds = promoImageIds; } @Override public int getCount(){ return promoImageIds.length; } @Override public Fragment getItem(int position) { return PromoFragment.newInstance( promoImageIds[position] ); } } public static class PromoFragment extends Fragment { int imageID; static PromoFragment newInstance( int imageID) { PromoFragment f = new PromoFragment(); // Supply num input as an argument. Bundle args = new Bundle(); args.putInt( "imageID", imageID ); f.setArguments(args); return f; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); imageID = getArguments() != null ? getArguments().getInt( "imageID" ) : null; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ImageView v = (ImageView) inflater.inflate(R.layout.fragment_image, container, false); v.setImageResource( imageID ); return v; } } } 

Encontré otra solución, basada en las respuestas de Shlomi Hasin y antonyt , sin modificar la colección.

 ViewPager yourPager; PagerAdapter yourAdapter; //.... EndlessPagerAdapter endlessPagerAdapter = new EndlessPagerAdapter(yourAdapter, yourPager); yourPager.setAdapter(endlessPagerAdapter); yourPager.setCurrentItem(1);//for correct first page 

Clase completa:

 public class EndlessPagerAdapter extends PagerAdapter { private PagerAdapter adapter; public EndlessPagerAdapter(PagerAdapter adapter, ViewPager viewPager) { this.adapter = adapter; viewPager.addOnPageChangeListener(new SwapPageListener(viewPager)); } @Override public int getCount() { return adapter.getCount() + 2; } @Override public Object instantiateItem(ViewGroup container, int position) { if (adapter.getCount() < 2) { adapter.instantiateItem(container, position); } int newPosition; if (position == 0) { newPosition = adapter.getCount() - 1; } else if (position >= getCount() - 1) { newPosition = 0; } else { newPosition = position - 1; } return adapter.instantiateItem(container, newPosition); } @Override public void destroyItem(ViewGroup container, int position, Object object) { adapter.destroyItem(container, position, object); } @Override public void finishUpdate(ViewGroup container) { adapter.finishUpdate(container); } @Override public boolean isViewFromObject(View view, Object object) { return adapter.isViewFromObject(view, object); } @Override public void restreState(Parcelable bundle, ClassLoader classLoader) { adapter.restreState(bundle, classLoader); } @Override public Parcelable saveState() { return adapter.saveState(); } @Override public void startUpdate(ViewGroup container) { adapter.startUpdate(container); } @Override public CharSequence getPageTitle(int position) { return adapter.getPageTitle(position); } @Override public float getPageWidth(int position) { return adapter.getPageWidth(position); } @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { adapter.setPrimaryItem(container, position, object); } @Override public void unregisterDataSetObserver(DataSetObserver observer) { adapter.unregisterDataSetObserver(observer); } @Override public void registerDataSetObserver(DataSetObserver observer) { adapter.registerDataSetObserver(observer); } @Override public void notifyDataSetChanged() { adapter.notifyDataSetChanged(); } @Override public int getItemPosition(Object object) { return adapter.getItemPosition(object); } private class SwapPageListener implements ViewPager.OnPageChangeListener { private ViewPager viewPager; SwapPageListener(ViewPager viewPager) { this.viewPager = viewPager; } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { if (state == ViewPager.SCROLL_STATE_IDLE) { PagerAdapter pagerAdapter = viewPager.getAdapter(); if (pagerAdapter != null) { int itemCount = pagerAdapter.getCount(); if (itemCount < 2) { return; } int index = viewPager.getCurrentItem(); if (index == 0 ) { viewPager.setCurrentItem(itemCount - 2, false); } else if (index == itemCount - 1) { viewPager.setCurrentItem(1, false); } } } } }} 

Cómo funciona:

Tenemos algo de colección

colección

luego agrega dos elementos adicionales

nuevo tamaño

mostrar el primer elemento en la última posición y el último elemento en la primera posición

mostrar elementos

agregar listener e intercambiar páginas en el evento, de 4 a 1 y de 0 a 3

intercambiar elementos

eso es todo.

No te aconsejaría que apliques animaciones allí o diseños pesados, puede estar rezagado cuando los elementos se intercambian. (Tal vez, no encontré rezagos)

Además, no configure este adaptador en buscapersonas más de una vez, o mueva SwapPageListener a una clase externa y configúrelo en el bloque de inicialización.

Para el desplazamiento infinito con días es importante que tengas el buen fragmento en el buscapersonas, por lo tanto escribí mi respuesta en esta página ( Viewpager en Android para cambiar entre días interminablemente )

¡Está funcionando muy bien! Las respuestas anteriores no me funcionaron porque quería que funcionaran.

RecyclerViewPager ha implementado infinite scrolling y puede desplazarse como una galería.

  if ((pagerBottom.getCurrentItem() + 1) == (sliderimageDetails.size())) { pagerBottom.setCurrentItem(0); } else { pagerBottom.setCurrentItem((pagerBottom.getCurrentItem() + 1)); }