2012-05-08 15 views
20

Estoy creando una aplicación que utiliza ActionBarSherlock. La aplicación consta de tres pestañas, y en cada una de ellas, se muestran varias pantallas consecutivamente según la entrada del usuario. Soy capaz de cambiar Fragmentos entre pestañas, pero la conmutación de fragmentos dentro lengüetas da un problema. He tratado de esta manera:fragmentos de conmutación dentro de la pestaña

En la clase principal:

SingleStationFragment singleStationFragment = new SingleStationFragment(); 
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
transaction.replace(android.R.id.content, singleStationFragment); 
transaction.addToBackStack(null); 
transaction.commit(); 

Este qué reemplazar el primer fragmento de la segunda, pero cuando cambio pestañas, el segundo fragmento es aún visible, mostrando el contenido de la nueva pestaña en la parte superior del contenido de la pestaña anterior. Creo que de alguna manera tengo que separar el segundo fragmento en onTabUnselected, pero no tengo idea de cómo obtener una referencia a este Fragmento.

¿Puede alguien ayudarme con esto?

Para mayor claridad, algunas clases importantes:

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 "Adding Navigations Tabs" on the Android developer site 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) { 
    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; 
    } 
} 

    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 un 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); 
    } 
} 

Respuesta

24

Así que lo que ocurrió fue que, en TabListener, en el método onTabUnselected, el Fragment no fue extraído, provocando que todavía ser espectáculo mientras un nuevo Fragment se demostró.

La causa de esto fue que el Fragment que se separó fue el primer fragmento, y no mi segundo fragmento. He hecho algunos cambios.

En el Activity:

SingleStationFragment singleStationFragment = new SingleStationFragment(); 
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
transaction.replace(android.R.id.content, singleStationFragment, "STATIONS"); 
transaction.addToBackStack(null); 
transaction.commit(); 

Aquí He añadido la etiqueta "STATIONS" en el método replace(), que es la misma etiqueta como el primer fragmento.
El TabListener es ahora de la siguiente manera:

public class TabListener<T extends SherlockFragment> implements com.actionbarsherlock.app.ActionBar.TabListener { 
    private final SherlockFragmentActivity mActivity; 
    private final String mTag; 
    private final Class<T> mClass; 

    private SherlockFragment mFragment; 

    public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) { 
     mActivity = activity; 
     mTag = tag; 
     mClass = clz; 
    } 

    public void onTabSelected(Tab tab, FragmentTransaction ft) { 
     SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag); 
     if (preInitializedFragment == null) { 
      mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName()); 
      ft.add(R.id.treinverkeer_fragmentcontent, mFragment, mTag); 
     } else { 
      ft.attach(preInitializedFragment); 
     } 
    } 

    public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
     SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag); 

     if (preInitializedFragment != null) { 
      ft.detach(preInitializedFragment); 
     } else if (mFragment != null) { 
      ft.detach(mFragment); 
     } 
    } 

    public void onTabReselected(Tab tab, FragmentTransaction ft) { 
     // User selected the already selected tab. Usually do nothing. 
    } 
} 

En el método onTabUnselected ahora primero recuperar la correcta Fragment, a continuación, extráigalo.

Esperamos que esto ayude a alguien!

+2

Gracias hombre, lo hizo ayudar a alguien. – NotCamelCase

+0

¿Podría por favor enviarme un código, esto es exactamente lo que estoy tratando de hacer. – user1730789

+0

+1 Eso funcionó muy bien, gracias :)! – AgentKnopf

Cuestiones relacionadas