El contenido de la ficha permanece visible después de cambiar la pestaña después del cambio de orientación

Estoy utilizando ActionBarSherlock para implementar un ActionBar con pestañas en mi aplicación. Cuando inicio la aplicación y cambie de pestaña a pestaña, todo está bien. Sin embargo, cuando cambio de modo vertical a modo horizontal, el contenido de la ficha que fue la última vez activo permanece visible. Cambiar a otra ficha da como resultado el dibujo del nuevo contenido encima del contenido antiguo (ver imagen).

Introduzca aquí la descripción de la imagen

Mi clase principal:

 public class TreinVerkeer extends SherlockFragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setupTabs(savedInstanceState); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getSupportMenuInflater(); inflater.inflate(R.menu.menu, menu); return true; } private void setupTabs(Bundle savedInstanceState) { ActionBar actionBar = getSupportActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); Tab tab = actionBar.newTab().setText("STATIONS").setTabListener(new TabListener<StationsFragment>(this, "stations", StationsFragment.class)); actionBar.addTab(tab); tab = actionBar.newTab().setText("ROUTE").setTabListener(new TabListener<RouteFragment>(this, "route", RouteFragment.class)); actionBar.addTab(tab); tab = actionBar.newTab().setText("DELAYS").setTabListener(new TabListener<DelaysFragment>(this, "delays", DelaysFragment.class)); actionBar.addTab(tab); if (savedInstanceState != null) { actionBar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0)); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex()); } } 

TabListener (desde "Agregar pestañas de navegación" en el sitio de desarrolladores de Android con algunos cambios menores):

 public class TabListener<T extends SherlockFragment> implements com.actionbarsherlock.app.ActionBar.TabListener { private SherlockFragment mFragment; private final Activity mActivity; private final String mTag; private final Class<T> mClass; /** * Constructor used each time a new tab is created. * * @param activity * The host Activity, used to instantiate the fragment * @param tag * The identifier tag for the fragment * @param clz * The fragment's Class, used to instantiate the fragment */ public TabListener(Activity activity, String tag, Class<T> clz) { mActivity = activity; mTag = tag; mClass = clz; } /* The following are each of the ActionBar.TabListener callbacks */ public void onTabSelected(Tab tab, FragmentTransaction ft) { // Check if the fragment is already initialized if (mFragment == null) { // If not, instantiate and add it to the activity mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content, mFragment, mTag); } else { // If it exists, simply attach it in order to show it ft.attach(mFragment); } } public void onTabUnselected(Tab tab, FragmentTransaction ft) { if (mFragment != null) { // Detach the fragment, because another one is being attached ft.detach(mFragment); } } public void onTabReselected(Tab tab, FragmentTransaction ft) { // User selected the already selected tab. Usually do nothing. } } 

Y StationsFragment ( RouteFragment y DelaysFragment son iguales, con solo texto diferente)

 public class StationsFragment extends SherlockFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.stationsfragment, container, false); } } 

Con eso el archivo de diseño para StationsFragment :

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Stations" /> </LinearLayout> 

Y finalmente el archivo Manifest:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.myapp" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".TreinVerkeer" android:label="@string/app_name" android:theme="@style/Theme.Sherlock.Light" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 

Tuve el mismo problema antes de iniciar la aplicación (sin cambiar la orientación), esto se resolvió mediante la eliminación de setContentView(R.layout.main) en el onCreate de la clase principal. No puedo encontrar una solución para esto sin embargo. Puede alguien ayudarme con esto?

FragmentManager restaurará automáticamente cualquier fragmento (e historia) que se mostrara actualmente en un cambio de configuración. Llame a findFragmentByTag para ver si ya existe una instancia del fragmento de destino antes de crear y adjuntar una nueva instancia.

Gracias a Jake, he actualizado el método onTabSelected como este:

 public void onTabSelected(Tab tab, FragmentTransaction ft) { SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag); // Check if the fragment is already initialized if (mFragment == null && preInitializedFragment == null) { // If not, instantiate and add it to the activity mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content, mFragment, mTag); } else if (mFragment != null) { // If it exists, simply attach it in order to show it ft.attach(mFragment); } else if (preInitializedFragment != null) { ft.attach(preInitializedFragment); mFragment = preInitializedFragment; } } 

Esta respuesta es para propósitos de aclaración solamente, los créditos van a Jake 🙂

Además de los cambios que Niek publicó, hay un par de cambios triviales que debes hacer. Principalmente cambiando la actividad a SherlockFragmentActivity.

Para el beneficio de los demás, aquí está mi versión final que parece funcionar correctamente.

  public static class TabListener<T extends SherlockFragment> implements ActionBar.TabListener { private SherlockFragment mFragment; private final SherlockFragmentActivity mActivity; private final String mTag; private final Class<T> mClass; /** Constructor used each time a new tab is created. * @param activity The host Activity, used to instantiate the fragment * @param tag The identifier tag for the fragment * @param clz The fragment's Class, used to instantiate the fragment */ public TabListener(Activity activity, String tag, Class<T> clz) { mActivity = (SherlockFragmentActivity) activity; mTag = tag; mClass = clz; } public void onTabSelected(Tab tab, FragmentTransaction ft) { // Check if the fragment has already been initialised SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag); if (mFragment != null) { // If it exists, simply attach it in order to show it ft.attach(mFragment); } else if (preInitializedFragment != null) { mFragment = preInitializedFragment; ft.attach(mFragment); } else { // Not found, so instantiate and add it to the activity mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content, mFragment, mTag); } } public void onTabUnselected(Tab tab, FragmentTransaction ft) { if (mFragment != null) { // Detach the fragment, because another one is being attached ft.detach(mFragment); } } public void onTabReselected(Tab tab, FragmentTransaction ft) { // User selected the already selected tab. Usually do nothing. } } 
  • Ficha que no toma el ancho completo en el dispositivo Tablet
  • Obtener una URL de pestaña desde la acción de la página (WebExtensions, Android)
  • Barra de Acción de Android Icono de Sherlock para cada pestaña de recursos
  • No se puede mostrar 2 instancias de mi SurfaceView personalizado
  • Cómo cambiar el color del texto del indicador de tabs en android?
  • Cambiar el estilo de fuente en las pestañas de la barra de acción con Sherlock
  • Android 2.1 NullPointerException con TabWidgets
  • Cómo hacer scrollable tab en Android?
  • Android: ¿Por qué no debo usar actividades dentro de pestañas?
  • TabLayout Tab Título del texto en minúscula
  • Android: el uso de la memoria aumenta cada vez que se hace clic en la pestaña (cuando se utiliza el grupo de actividades)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.