2012-05-08 2 views
20

Je crée une application qui utilise ActionBarSherlock. L'application se compose de trois onglets, et dans chacun d'eux, plusieurs écrans sont affichés consécutivement en fonction de l'entrée de l'utilisateur. Je suis capable de basculer Fragments entre les onglets, mais la commutation des fragments dans les onglets donne un problème. Je l'ai essayé comme ceci:Changement de fragments dans l'onglet

Dans la classe principale:

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

Ce ne remplace le premier fragment de la seconde, mais quand je change les onglets, le second fragment est encore visible, montrant le contenu du nouvel onglet en plus du contenu de l'ancien onglet. Je pense que j'ai besoin de détacher le deuxième fragment en onTabUnselected, mais je ne sais pas comment obtenir une référence à ce fragment.

Quelqu'un peut-il m'aider avec ceci?

Pour plus de clarté, certaines classes importantes:

Ma principale classe:

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

Le TabListener (de "Adding Navigations Tabs" on the Android developer site avec quelques modifications mineures):

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. 
    } 
} 

Et StationsFragment (RouteFragment et DelaysFragment sont les mêmes, avec seulement un texte différent)

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

Répondre

24

Qu'est-il arrivé était que, dans TabListener, dans la méthode onTabUnselected, la Fragment n'a pas été détaché, l'amenant à être encore un nouveau spectacle en Fragment a été montré.

La cause de ceci était que le Fragment qui était détaché était le premier fragment, et non mon second fragment. J'ai fait quelques changements.

Dans le Activity:

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

Ici, j'ai ajouté la balise "STATIONS" dans la méthode replace(), qui est la même étiquette que le premier fragment.
Le TabListener est maintenant comme suit:

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. 
    } 
} 

Dans la méthode onTabUnselected je maintenant d'abord récupérer la Fragment correcte, puis retirez-le.

Espérons que cela aide quelqu'un!

+2

Merci, ça a aidé quelqu'un. – NotCamelCase

+0

Pourriez-vous s'il vous plaît m'envoyer du code, c'est exactement ce que j'essaie de faire. – user1730789

+0

+1 Cela a très bien fonctionné, merci :)! – AgentKnopf