Fragmentos no funcionan correctamente después de cambio de orientación

Tengo un problema con Fragments y cambio de orientación.

Tengo una aplicación que tiene una MainActivity que maneja la conmutación de Fragments través de una barra de acción con pestañas. Aquí está el código de la barra de acción con pestañas y cuando se selecciona una pestaña.

 private class MyTabListener <T extends android.support.v4.app.Fragment> implements ActionBar.TabListener { private android.support.v4.app.Fragment mFragment; private final Activity mActivity; private final String mTag; private final Class<T> mClass; public MyTabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) { mActivity = activity; mTag = tag; mClass = clz; } @Override public void onTabSelected(Tab tab, android.support.v4.app.FragmentTransaction ft) { if (mFragment == null){ // check to see if the fragment has already been initialised. If not create a new one. mFragment = android.support.v4.app.Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content,mFragment,mTag); } else { ft.attach(mFragment); // if the fragment has been initialised attach it to the current activity } } @Override public void onTabUnselected(Tab tab, android.support.v4.app.FragmentTransaction ft) { if (mFragment != null){ ft.detach(mFragment); // when a fragment is no longer needed, detach it from the activity but dont destroy it } } @Override public void onTabReselected(Tab tab, android.support.v4.app.FragmentTransaction ft) { } 

La manera que lo veo es que todo trabaja muy bien cuando la aplicación primero carga en modo del retrato. Cuando roto, por alguna razón se agrega otra instancia de Fragment1 y luego no se desprende cuando se selecciona otra pestaña. Este es también el caso cuando vuelvo a girar de nuevo al retrato.

He intentado usar setRetainInstance(true); En mis Fragments pero esto no funciona.

¿Hay un método que necesito para anular o hacer algo con mis Fragments antes de girar?

Gracias por adelantado.

EDIT Ahora he visto que onTabSelected se llama de nuevo cuando la actividad es recreada. ¿Podría esto ser la causa de mi problema con los fragmentos que se atan más de una vez?

Aquí está mi método onCreate de actividades.

 super.onCreate(savedInstanceState); if (savedInstanceState == null) { //setContentView(R.layout.main); } // Create the Action Bar with tabs ActionBar actionBar = getSupportActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBar.setDisplayShowTitleEnabled(false); //create the tab for track and add it to the action bar. Tab tab = actionBar.newTab() .setText("Track") .setTabListener(new MyTabListener<TrackingFragment>(this,"track",TrackingFragment.class)); actionBar.addTab(tab); //create the tab for ski tracks and add it to the action bar. tab = actionBar.newTab() .setText("Something Tracks") .setTabListener(new MyTabListener<TrackListFragment>(this,"somethingtracks",TrackListFragment.class)); actionBar.addTab(tab); //create the tab for photos and add it to the action bar. tab = actionBar.newTab() .setText("Photos") .setTabListener(new MyTabListener<PhotoFragment>(this,"photos",PhotoFragment.class)); actionBar.addTab(tab); 

5 Solutions collect form web for “Fragmentos no funcionan correctamente después de cambio de orientación”

Corto arreglo:

En el método onTabSelected , antes de usar if (mFragment == null) es necesario intentar obtener el fragmento (usando mFragment = getSupportFragmentManager().findFragmentByTag(mTag) ). También puede establecer esto desde el exterior, pero no te veo haciendo esto.

Comprobar if(savedInstanceState == null) en onCreate también podría resolver esto y lo considero un enfoque mejor sin embargo! 🙂

Parece que no tienes algo en tu método onCreate envuelto en un if(savedInstanceState == null) , por lo que estás creando otro fragmento además del que está siendo restaurado desde el paquete savedInstanceState.

EDITAR

Mirando más de cerca su código, creo que estaba equivocado sobre el onCreate, su onTabSelected debe manejarlo. Creo que tu if (mFragment == null) siempre viene nulo, porque no intentas encontrar el fragmento. Cambiar esa sección de código a:

 @Override public void onTabSelected(Tab tab, android.support.v4.app.FragmentTransaction ft) { mFragment = mActivity.getSupportFragmentManager().findFragmentByTag(mTag); // add this if (mFragment == null){ // check to see if the fragment has already been initialised. If not create a new one. mFragment = android.support.v4.app.Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content,mFragment,mTag); } else { ft.attach(mFragment); // if the fragment has been initialised attach it to the current activity } } 

Me enteré de que setRetainInstance es realmente ignorado y todos los fragmentos creados por el android.support.v4.app.FragmentManager se almacenan en onSaveInstanceState y se recrean en onCreate .

Para mí, la solución fue borrar sin rodeos el fragmento guardado de forma superflua: https://stackoverflow.com/a/13996054/341091

Tuve más o menos el mismo problema, pero las soluciones presentadas anteriormente no parecen funcionar en mi situación. Finalmente encontré la siguiente solución:

 @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { if (mFragment == null) { mFragment = Fragment.instantiate(mActivity, mClass.getName()); ft.replace(android.R.id.content, mFragment, mTag); // Use replace iso add } else { ft.attach(mFragment); } } 

If (savedInstanceState == null) no está funcionando siempre. A veces savedInstanceState! = Null mientras se necesita agregar otro fragmento debido a la orientación horizontal.

Otra aproximación es probar si fm.findFragmentById (R.id.frameLayoutLeft), no importa cuál sea la orientación, es nulo o no, en caso afirmativo, que crear una nueva instancia de fragmento de otra manera no hacer nada. Si necesita un segundo fragmento en modo horizontal, primero debe comprobar si es horizontal o no, de ser así, compruebe si fm.findFragmentById (R.id.frameLayoutRight) es nulo o no. Si nulo, que crear, de lo contrario no hacer nada porque ya está allí retenido por Android OS.

  • Fragmentos lentos Android TabHost lento
  • Objetos de comunicación entre fragmentos múltiples en ViewPager
  • Cómo destruir fragmentos antiguos en FragmentStatePagerAdapter
  • Android TabLayout ViewPager no inflar el fragmento de la pestaña en backstack
  • FragmentPagerAdapter - evita la recreación de las vistas de fragmentos
  • FragmentStatePagerAdapter no quita fragmentos si se eliminó el fragmento padre
  • Fragmento desaparece de la espalda
  • ¿Cómo llamo a un PreferenceFragment específico de una PreferenceActivity?
  • Mejores prácticas de fragmentos
  • ViewPager tiene datos de offset incorrectos después de girar la pantalla cuando la página actual no es la primera
  • Obtener referencia al fragmento anidado de FragmentTabHost
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.