ViewPager Adapter getItem siempre llamado para el índice 0 y 1

Me preguntaba si es el comportamiento normal de viewpager y su adaptador para llamar siempre el método de getItem() para el índice 0 y 1, aunque inmediatamente getItem() una posición actual.

Aquí está mi código:

 mNewsPagerAdapter = new NewsDetailPagerAdapter(getChildFragmentManager()); mNewsPagerAdapter.updateNewsList(news); mViewPager = (ViewPager) mView.findViewById(R.id.horizontal_view_pager); mViewPager.setPageMargin(2); mViewPager.setPageMarginDrawable(R.color.black); mViewPager.setAdapter(mNewsPagerAdapter); mViewPager.setCurrentItem(mCurrentPositionPager, false); 

Si cambio de mi actividad de resumen a mi actividad de detalle con este viewpager , el adaptador siempre llama al método getItem() para la posición 0 y 1 y después el método getItem() para la posición de mOriginalPosition y sus vecinos. Me preguntaba si este es el comportamiento correcto o si me perdí algo para implementarlo de una manera correcta. Gracias por tu ayuda 🙂

Editar: Añadido el código del adaptador

 public class NewsDetailPagerAdapter extends FragmentStatePagerAdapter { private SparseArray<Fragment> mPageReferenceMap = new SparseArray<Fragment>(); private ArrayList<News> mNewsList; public NewsDetailPagerAdapter(FragmentManager fm) { super(fm); } /** * Setzt die neuen News. **/ public void updateNewsList(ArrayList<News> list) { mNewsList = list; } @Override public Fragment getItem(int position) { Log.d("debug", "getItem position:" + position); News newsItem = mNewsList.get(position); NavigationFragment fragment = new NavigationFragment(); mPageReferenceMap.put(position, fragment); return fragment; } @Override public int getCount() { return mNewsList.size(); } @Override public int getItemPosition(Object object) { return POSITION_NONE; } public Fragment getFragment(int position) { return mPageReferenceMap.get(position); } 

}

4 Solutions collect form web for “ViewPager Adapter getItem siempre llamado para el índice 0 y 1”

En realidad este es el comportamiento normale. De hecho, como soos cuando asocia ViewPager con el adaptador, el adaptador crea el primer diseño visibile (índice 0) y el siguiente (índice 1). Esto se hace por defecto en el "setAdapter". Luego, al establecer una posición diferente, el adaptador instanciará el fragmento en el índice seleccionado, el anterior y el siguiente.

Este es el código del setAdapter de ViewPager:

 public void setAdapter(PagerAdapter adapter) { if (mAdapter != null) { mAdapter.setViewPagerObserver(null); mAdapter.startUpdate(this); for (int i = 0; i < mItems.size(); i++) { final ItemInfo ii = mItems.get(i); mAdapter.destroyItem(this, ii.position, ii.object); } mAdapter.finishUpdate(this); mItems.clear(); removeNonDecorViews(); mCurItem = 0; scrollTo(0, 0); } final PagerAdapter oldAdapter = mAdapter; mAdapter = adapter; mExpectedAdapterCount = 0; if (mAdapter != null) { if (mObserver == null) { mObserver = new PagerObserver(); } mAdapter.setViewPagerObserver(mObserver); mPopulatePending = false; final boolean wasFirstLayout = mFirstLayout; mFirstLayout = true; mExpectedAdapterCount = mAdapter.getCount(); if (mRestoredCurItem >= 0) { mAdapter.restoreState(mRestoredAdapterState, mRestoredClassLoader); setCurrentItemInternal(mRestoredCurItem, false, true); mRestoredCurItem = -1; mRestoredAdapterState = null; mRestoredClassLoader = null; } else if (!wasFirstLayout) { populate(); } else { requestLayout(); } } if (mAdapterChangeListener != null && oldAdapter != adapter) { mAdapterChangeListener.onAdapterChanged(oldAdapter, adapter); } } 

Para cambiar el comportamiento de ViewPager, puede extender el ViewPager clásico que sobrepasa el método setAdapter y establecer el mCurrItem en la posición deseada.

Espero que ayudara

Editar:

Después de diferentes pruebas, encontramos una solución.

Si el adaptador ViewPager se establece después de que el diseño ViewPager se vuelve visible, los elementos 0 y 1 se cargan. Si desea evitar este comportamiento, pero no puede establecer el adaptador antes de que el diseño se vuelva visible (porque está esperando datos), de lo que puede utilizar esta solución:

1) Establezca primero la visibilidad de ViewPager en GONE

2) Después de recibir todos los datos, actualiza el adaptador y establece el valor del elemento actual

3) Por último, se establece la visibilidad ViewPager VISIBLE

Aquí puede encontrar un ejemplo:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.detail_overview_fragment, container, false); final int position = getArguments().getInt("position"); final ViewPager viewPager = (ViewPager) v.findViewById(R.id.viewpager); viewPager.setVisibility(View.GONE); Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { viewPager.setAdapter(new PagerAdapter(getChildFragmentManager())); viewPager.setCurrentItem(position); viewPager.setVisibility(View.VISIBLE); } },5000); return v; } 

Sí, este es el comportamiento normal de ViewPager, ya que siempre tratará de mantenerse a la vanguardia del usuario al representar las pestañas que limitan con el área de dibujo. Personalmente, no recomiendo crear un ViewPager personalizado, ya que está casi seguro de romper la funcionalidad a menos que realmente sepa lo que está haciendo. Su clase de adaptador debería verse así:

 public class YourCustomPagerAdapter extends FragmentStatePagerAdapter { private List<Fragment> fragmentList = new ArrayList<>(); private List<String> titleList = new ArrayList<>(); public WizardPagerAdapter(FragmentManager fm) { super(fm); } public void addFragment(Fragment fragment, String title) { fragmentList.add(fragment); titleList.add(title); } @Override public Fragment getItem(int position) { return fragmentList.get(position); } @Override public CharSequence getPageTitle(int position) { super.getPageTitle(position); return titleList.get(position); } @Override public int getCount() { return fragmentList.size(); } } 

Y debe agregar sus fragmentos como tal:

  @Override public void onCreate(Bundle savedInstanceState) { ... YourCustomPagerAdapter adapter = new YourCustomPagerAdapter (getSupportFragmentManager()); adapter.addFragment(FragmentOne.newInstance(), "Frag 1"); adapter.addFragment(FragmentTwo.newInstance(), "Frag 2"); viewPager.setAdapter(adapter); ... } 

Es normal (e inteligente en mi opinión). La clase ViewPager tiene una propiedad denominada mOffscreenPageLimit con el valor por defecto de 1. Este número determina cuántas páginas a la izquierda y derecha de la página actual que el Viewpager precargará. Por ejemplo, tiene 10 páginas, la posición actual es 5 y mOffcreenPageLimit es 1, la página en la posición 4 y 6 se cargará.

Puede cambiar esta propiedad llamando a este método

 viewpager. setOffscreenPageLimit(int) 

Si pasa un entero que es menor que 1, no tiene ningún efecto.

Creo que el error es el adaptador:

  /** * Setzt die neuen News. **/ public void updateNewsList(ArrayList<News> list) { //mNewsList = list; mNewsList.clear(); mNewsList.addAll(list); /** * Notifies the attached observers that the underlying data has been changed * and any View reflecting the data set should refresh itself. */ this.notifyDataSetChanged(); } 

Razón de error: esta lista es entidad diffent para ese adaptador.

  • Textview en el botón (arriba), no funciona en Android 5 (API 21)
  • Android: ¿Cómo obtener el actual desplazamiento X de RecyclerView?
  • ¿Hay una forma de compensar una vista desde el centro en Android?
  • ¿Configurar el pulgar en una posición particular (no en el desplazamiento) de seekbar mediante programación?
  • Establecer la posición absoluta de una vista
  • android detecta si el usuario ha rozado
  • Cómo cambiar la posición de inicio de la pista de Android SeekBar?
  • Cambio de fondo del elemento de vista de lista de Android
  • Adición dinámica de un niño a LinearLayout con la obtención de la posición de cada niño
  • Combinando wrap_content en el padre y fill_parent en el niño
  • Android canvas drawText y-posición del texto
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.