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).
- PreferenceFragment crashing, objeto nulo Referencia
- ¿Cómo agregar otro fragmento en el fragmento existente?
- Circular ViewPager. Fragmentos no funcionan como se suponía después de la primera ronda
- Diferentes SoftInputMode en la misma Actividad, ¿es posible?
- App se está estrellando en la parte posterior presionado cuando el uso de mapa dentro de fragmento en android?
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
- Cargar un fragmento al hacer clic en CardView desde RecyclerView
- Android Master / Detalle de flujo dentro de ViewPager
- El fragmento es transparente y muestra la actividad a continuación
- Android 4.4 - Estado translúcido / barras de navegación - fitsSystemWindows / clipToPadding no funcionan con transacciones de fragmentos
- Contextthemewrapper no se puede transmitir a la actividad
- Android: en el interruptor de desplazamiento entre Vistas / Actividades / Fragmentos
- ListView dentro de un fragmento utilizado en un ViewPager no se comporta como se esperaba
- No se puede obtener gridView en el elemento de escucha de clics
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:
-
No llame al
super.onSaveInstanceState()
de su actividad, pero no parece una buena solución, los fragmentos no pueden guardar el estado y restaurar. -
Utilice
FragmentPagerAdapter
lugar deFragmentStatePagerAdapter
. Pero después de cambiar la orientación, los fragmentos queViewPager
alojado fue borrado (¿Alguien más tiene el mismo problema?). Pero puedo quitar todos los fragmentos enActivity.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
- Imageview método de escala "centercrop" como código
- Manejo de la prensa trasera al utilizar fragmentos en Android