ViewPager + FragmentStatePagerAdapter + cambio de orientación

Tengo un pequeño problema: tengo un ViewPager con algunas páginas y utilizo el FragmentStatePagerAdapter para manejar los datos. En el retrato tengo por ejemplo 20 páginas para el ViewPager y en paisaje tengo apenas 10 páginas para el ViewPager. Así que en un cambio de orientación creo un nuevo adaptador con diferentes datos.

Aquí una pequeña explicación de por qué: Muestra una imagen en el retrato y dos en el paisaje, pero siempre en cuenta. Si tengo 10 fotos para mostrar, tengo 10 en retrato y 5 en paisaje (siempre dos).

Pero ahora tengo un error extraño: Cuando estoy en el paisaje en el índice 5 y girar el dispositivo, la página actual del ViewPager se establece en 10. Si vuelvo a girar de nuevo estoy en la página 5. Si ahora deslizar el ViewPage a la página 10 el método getItem del adaptador nunca se llama y el ViewPage me muestra la imagen de un retrato y no los dos para el paisaje. ¿Cómo puede suceder esto? ¿Hay un caché en el adaptador o ViewPager? En el onCreate de la actividad todo es nuevo creado, el adaptador y también los datos (sólo las cadenas con la ruta) para el ViewPager. Así que cualquier idea de cómo arreglar esta "característica" realmente aterrador?

He aquí algunos códigos:

OnCreate:

mViewPagerAdapter = new ReaderPageViewAdapter(getSupportFragmentManager(), getBaseContext(), mCurrentDocument.mPages, getResources() .getConfiguration().orientation); mPageReader = (ReaderViewPager) findViewById(R.id.pager); mPageReader.setAdapter(mViewPagerAdapter); 

Adaptador getItem:

  public Fragment getItem(final int index) { final PageInfo pageInfo = mPages.get(index); final PageFragment pageFragment = (PageFragment) PageFragment .instantiate(mContext, pageInfo.mClss.getName(), pageInfo.mArgs); return pageFragment; } 

Si necesitas algo más, dímelo. Gracias

Puede sobrescribir el FragmentActivity onSaveInstanceState () y no llamar al super.onSaveInstanceState () en el método.

 @Override protected void onSaveInstanceState(final Bundle outState) { // super.onSaveInstanceState(outState); } 

No utilice mViewPager.setSaveEnabled(false);

Terminó con un memoryLeak grande. Después de cada cambio de orientación, coloca los Fragmentos en una matriz de FragmentManager y nunca lo limpia. Por lo que sube a más de 100 MB de uso de memoria después de cambiar la orientación muchas veces. Usar el método onSaveInstanceState es una mejor manera de pensar.

También me ocurrió este problema y encontré la razón.

Cada vez que se gira la pantalla, el FragmentManager retendrá todos los fragmentos alojados en su actividad, no quitará fragmentos Si utiliza FragmentStatePagerAdapter , puede utilizar FragmentManager.getFragments() para comprobar el número de fragmentos.

Ejemplo: La actividad tiene 4 fragmentos, Después de 4 veces el cambio de orientación, el tamaño de la lista FragmentManager.getFragments() será 20 !

He encontrado algunas soluciones:

  1. No llame al super.onSaveInstanceState() de su actividad, pero no parece una buena solución, los fragmentos no pueden guardar el estado y restaurar.

  2. Utilice FragmentPagerAdapter lugar de FragmentStatePagerAdapter . Pero después de cambiar la orientación, los fragmentos que ViewPager alojado fue borrado (¿Alguien más tiene el mismo problema?). Pero puedo quitar todos los fragmentos en Activity.onCreate para arreglarlo. Me gusta esto:

     public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FragmentManager fm = getSupportFragmentManager(); List<Fragment> fragments = fm.getFragments(); if (fragments != null) { FragmentTransaction transaction = fm.beginTransaction(); for (Fragment fragment : fragments) { transaction.detach(fragment).remove(fragment); } transaction.commitNowAllowingStateLoss(); } ... 

    Pero el Fragment.onCreateView() llamó dos veces.

Todavía estoy buscando la solución perfecta: D

Editar:
Finalmente resuelto el problema, es porque mi ViewPager se agrega después de onStart. Cuando se ejecuta a onStart, el FragmentManager intentará restaurar el estado de fragmentos. He rastreado en FragmentManager , Tengo estos código:

Com / android / support / support-fragment / 24.2.1 / support-fragment-24.2.1-sources.jar! /android/support/v4/app/FragmentManager.java

Compruebe la línea de resaltado, El f.mContainerId realidad es mi ID de ViewPager. Entonces intentará agregar la visión de los fragmentos al ViewPager, en mi caso, el ViewPager no es agregado todavía, así que será blanked, pero los fragmentos son estado ATTACHED . Y en FragmentPagerAdapter.instantiateItem() , Si el fragmento se agregó, Sólo attach el fragmento, Pero el fragmento ya está adjunto, Por lo tanto, no hacer nada 🙁

Añadir ViewPager a la disposición XML de la disposición, su fijo.

Codificación feliz: D

Sólo se utiliza en viewPager.setonpagechangelistener e implementar para solicitar código aplicar su aplicación,

http://developer.android.com/reference/android/support/v4/view/ViewPager.html

  • Detección de Android en el fragmento táctil dentro
  • MapFragment en Fragment, alternativas?
  • Tecla Atrás en Fragmento añadido mediante programación lleva a contenedor vacío
  • Android: la pantalla del fragmento gira
  • Android: mostrar / ocultar fragmento deja un área vacía
  • Cómo guardar el estado del fragmento teniendo listview
  • Mostrar fragmento como un diálogo o como una actividad habitual
  • ¿Cómo detener atrás pulsar el botón de volver a cada fragmento que se abrió en la actividad?
  • El video no se detiene en el fragmento ViewPager
  • Fragmentos en ViewPager se recrean
  • Reutilizando fragmentos en un fragmento
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.