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.

  • ¿Cómo puede manejar el descarte de un DialogFragment (compatibilidad lib) al completar un AsyncTask
  • Bauerca drag-sort-listview ejemplo sencillo
  • Fragmento de lanzamiento por nombre de variable
  • ViewPager + FragmentStatePagerAdapter: ViewPager deja de funcionar cuando cambia la orientación de la pantalla
  • Android cómo abrir el fragmento del elemento listview
  • ¿Cómo puedo fragmento pop de backstack sin reanudarlo?
  • Obtener imagen de la galería para establecer en imageview en fragmento?
  • Fragmento crear / restaurar una vista duplicada cuando vuelva a conectar
  • ¿Cómo implementar el Menú de Dos Niveles usando el Cajón de Navegación de Android?
  • Java.lang.IllegalStateException: Fragmento ya agregado
  • ¿Las pestañas anidadas con el visor de desplazamiento en android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.