studio - manual de programacion android pdf
El contenido de la pestaña permanece visible después de cambiar la pestaña después del cambio de orientación (3)
Gracias a Jake, actualicé el método onTabSelected
así:
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 sólo para aclaración, los créditos van a Jake :)
Estoy usando ActionBarSherlock
para implementar una ActionBar
con pestañas en mi aplicación. Cuando inicio la aplicación y cambio de pestaña a pestaña, todo está bien. Sin embargo, cuando cambio del modo retrato al modo paisaje, el contenido de la última pestaña activa permanece visible. Cambiar a otra pestaña da como resultado el dibujo del nuevo contenido sobre el contenido anterior (ver 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());
}
}
El TabListener (de "Agregar pestañas de navegación" en el sitio del desarrollador 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 al momento de iniciar la aplicación (sin cambiar la orientación), esto se solucionó al eliminar setContentView(R.layout.main)
en la onCreate
de la clase principal. Sin embargo, no puedo encontrar una solución para esto. Puede alguien ayudarme con esto?
FragmentManager
restaurará automáticamente cualquier fragmento (y el historial) que se muestre 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.
Además de los cambios que publicó Niek, hay un par de cambios triviales que debes hacer. Principalmente simplemente cambiando la actividad a SherlockFragmentActivity.
Para el beneficio de otros, 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.
}
}