IllegalStateException: El PagerAdapter de la aplicación cambió el contenido del adaptador sin llamar a PagerAdapter # notifyDataSetChanged

Estoy usando el ejemplo de ActionBar con ActionBar pestañas de ActionBar tomadas de la documentación de Android aquí .

Desafortunadamente, tan pronto como llamo al método addTab , la aplicación se bloquea con la siguiente excepción:

IllegalStateException: El PagerAdapter de la aplicación cambió el contenido del adaptador sin llamar a PagerAdapter # notifyDataSetChanged! Cantidad esperada de elementos del adaptador 0, encontrada 1.

Este es el código FragmentPagerAdapter :

 public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener { private final Context mContext; private final ActionBar mActionBar; private final ViewPager mViewPager; private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); static final class TabInfo { private final Class<?> clss; private final Bundle args; TabInfo(Class<?> _class, Bundle _args) { clss = _class; args = _args; } } public TabsAdapter(Activity activity, ViewPager pager) { super(activity.getFragmentManager()); mContext = activity; mActionBar = activity.getActionBar(); mViewPager = pager; mViewPager.setAdapter(this); mViewPager.setOnPageChangeListener(this); } public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) { TabInfo info = new TabInfo(clss, args); tab.setTag(info); tab.setTabListener(this); mTabs.add(info); mActionBar.addTab(tab); notifyDataSetChanged(); } @Override public int getCount() { return mTabs.size(); } @Override public Fragment getItem(int position) { TabInfo info = mTabs.get(position); return Fragment.instantiate(mContext, info.clss.getName(), info.args); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { mActionBar.setSelectedNavigationItem(position); } @Override public void onPageScrollStateChanged(int state) { } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { Object tag = tab.getTag(); for (int i=0; i<mTabs.size(); i++) { if (mTabs.get(i) == tag) { mViewPager.setCurrentItem(i); } } } @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { } @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { } } } 

No estoy modificando mi adaptador en ninguna otra parte de mi código y estoy llamando al método addTab del hilo principal, el método addTab termina con una llamada a notifyDataSetChanged . Como la documentación recomienda hacer:

PagerAdapter admite cambios en el conjunto de datos. Los cambios de conjunto de datos deben producirse en el subproceso principal y deben finalizar con una llamada a notifyDataSetChanged () similar a adaptadores AdapterView derivados de BaseAdapter.

Tuve dificultades para hacer que mi ViewPager funcionara. Al final, parece que el ejemplo en la documentación es incorrecto.

El método addTab debe ser como sigue:

 public void addTab(Tab tab, Class<?> clss, Bundle args) { TabInfo info = new TabInfo(clss, args); tab.setTag(info); tab.setTabListener(this); mTabs.add(info); notifyDataSetChanged(); mActionBar.addTab(tab); } 

Observe el orden de las tres últimas operaciones. En el ejemplo original, notifyDataSetChanged se llamó después de la función mActionBar.addTab .

Lamentablemente, tan pronto como se llama a la addTab en la ActionBar , la primera pestaña que agregue se selecciona automáticamente. Debido a esto, se onTabSelected evento onTabSelected y al intentar recuperar la página, muestra la IllegalStateException porque detecta una discrepancia entre el recuento de elementos esperados y el actual.

Lo arreglé por callinig notifyDataSetChanged () una vez y justo antes de la siguiente llamada de getCount ():

 private boolean doNotifyDataSetChangedOnce = false; @Override public int getCount() { if (doNotifyDataSetChangedOnce) { doNotifyDataSetChangedOnce = false; notifyDataSetChanged(); } return actionBar.getTabCount(); } private void addTab(String text) { doNotifyDataSetChangedOnce = true; Tab tab = actionBar.newTab(); tab.setText(text); tab.setTabListener(this); actionBar.addTab(tab); } private void removeTab(int position) { doNotifyDataSetChangedOnce = true; actionBar.removeTabAt(position); } 

Estaba recibiendo este error como usted haciendo referencia a las pestañas dentro de getCount ():

 @Override public int getCount() { return mTabs.size(); } 

Cuando instanciado esto debe ser pasado como una variable independiente, o el buscapersonas debe ser configurado después de que la colección se ha poblado / mutado.

Mi problema no era exactamente el mismo, sino un contexto similar.

Tengo un AlertDialog conseguir demostrado en una disposición que tenga ViewPager y esté utilizando AppCompatActivity. Estaba recibiendo el IllegalStateException y se bloqueaba al girar la pantalla.

Gracias a las respuestas de @almisoft respuesta y @ Zagorax, he intentado llamar a notifyDataSetChanged(); Justo antes de mostrar el diálogo, y el problema parece haber desaparecido.

Tuve el mismo problema en FragmentStatePager adaptador. onResume() Cuando reInitialize el adpater y ViewPager , se ViewPager el mismo error IllegalStateException . La solución:

Al agregar la ficha addtab , elija la pestaña que no se seleccionará estableciendo setSelected params como false.

  actionBar.addTab(tab,false); 

Creo que la excepción apareció por sobreescribir el método onTabSelected() como el siguiente

  viewPager.setCurrentItem(tab.getPosition()); 

Así que al llamar a addTab() no reconocía qué viewPager y el adaptador para agregar la pestaña a.

prueba esto. Yo trabajé

 protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); System.out.println("Asyncrona onPostExecute"); /*::::::::::::::::::: Guardo los cambios ::::::::::::::*/ //menuTabs = menuTabs2; viewPager = (ViewPager) rootView.findViewById(R.id.viewPager_menu); costumAdapter = new CostumAdapter2(getActivity().getSupportFragmentManager()); costumAdapter.notifyDataSetChanged(); viewPager.setAdapter(costumAdapter); tabLayout = (TabLayout) rootView.findViewById(R.id.tablayout_menu); tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { System.out.println(" La Seleccionado: " + tab.getText()+", POSICION: "+tab.getPosition()); viewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(TabLayout.Tab tab) { viewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabReselected(TabLayout.Tab tab) { viewPager.setCurrentItem(tab.getPosition()); } }); viewPager.setAdapter(costumAdapter); tabLayout.setupWithViewPager(viewPager); loading.closeMessage(); } 

Una respuesta de línea sólo tiene que agregar viewpageadapter.notifyDataSetChanded ()

  • IllegalStateException: No se puede cambiar la etiqueta del fragmento era android: switcher ahora android: switcher
  • Actualizar el fragmento actual en FragmentPagerAdapter
  • Cómo implementar un ViewPager con diferentes Fragmentos / Layouts
  • mantener instancias de fragmentos dentro de FragmentPagerAdapter
  • Cómo hacer que PagerAdapter cargue todas las páginas
  • No se puede cambiar la etiqueta del fragmento
  • Método de Fragmento tabulado de llamada de la actividad
  • Fragmentos de Viewpager y de Sherlock. ¿Cómo hacer somethng dentro de fragmento de FragmentActivity?
  • FragmentPagerAdapter con ViewPager y dos Fragmentos. Ir a la primera de la segunda y actualizar el primer texto
  • Android: limitar los fragmentos de carga con una viewPager
  • FragmentPagerAdapter getItem no está siendo activado
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.