Transaction entre fragments uniquement dans un onglet ActionBar

J'ai une application avec trois onglets (onglets ActionBar), chacun avec un fragment à la fois.

TabListener

  • Événement lorsque la vue de recherche se développe à partir de la vue iconifiée
  • Supprimez un fragment spécifique de l'Android Backstack
  • IU à deux panneaux avec Fragments vs Activités séparées
  • Appeler startActivity () de l'extérieur d'un contexte d'activité
  • Bibliothèque de support: les animations FragmentTransaction ne fonctionnent pas
  • Ajout dynamique de formes Opengl
  • TabsActivité

    Tab1 -> ListFragment1 -> ListFragment2 -> Fragment3

    Tab2 -> Tab2Fragment

    Tab3 -> Tab3Fragment

    Le problème est lorsque je crée le FragmentTransaction (à l'intérieur de OnListItemClicked) de ListFragment1 à ListFragment2, les fragments à l'intérieur des autres onglets changent également en ListFragment2.

    En fin de compte, je veux changer les fragments uniquement dans l'onglet et conserver l'état des autres onglets.

    Je sauvegarde déjà l'état (OnSavedInstance ()). Savez-vous ce que je manque ici?

    Une partie du code:

    public class TabsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.tabs); // setup Action Bar for tabs ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // instantiate fragment for the tab Fragment networksFragment = new NetworksFragment(); // add a new tab and set its title text and tab listener actionBar.addTab(actionBar.newTab().setText("Tab1") .setTabListener(new TabsListener(ListFragment1))); // instantiate fragment for the tab Fragment historyFragment = new HistoryFragment(); // add a new tab and set its title text and tab listener actionBar.addTab(actionBar.newTab().setText("Tab2") .setTabListener(new TabsListener(Tab2Fragment))); // instantiate fragment for the tab Fragment settingsFragment = new SettingsFragment(); // add a new tab and set its title text and tab listener actionBar.addTab(actionBar.newTab().setText("Tab3") .setTabListener(new TabsListener(Tab3Fragment))); } } 

     public class TabsListener implements ActionBar.TabListener { private Fragment frag; // Called to create an instance of the listener when adding a new tab public TabsListener(Fragment networksFragment) { frag = networksFragment; } @Override public void onTabReselected(Tab arg0, FragmentTransaction arg1) { // TODO Auto-generated method stub } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { ft.add(R.id.fragment_container, frag, null); } @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { ft.remove(frag); } } 

     public class ListFragment1 extends ListFragment { @Override public void onListItemClick(ListView l, View v, int position, long id) { getListView().setItemChecked(position, true); ListFragment2 fragment2 = ListFragment2.newInstance(position); FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(R.id.fragment_container, fragment2); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); ft.addToBackStack(null); ft.commit(); } } 

    One Solution collect form web for “Transaction entre fragments uniquement dans un onglet ActionBar”

    Vous ne manquez rien (ou je l'ai manqué aussi).

    J'ai cherché longtemps et dur pour une façon de le faire «correctement» mais je n'ai rien trouvé. Ce que j'ai fini, c'est d'écrire ma propre logique de backstack. Malheureusement, mon employeur est propriétaire de mon code, de sorte que je ne peux pas partager l'un de ces termes, mais voici mon approche:

    Créez une enum avec une entrée pour chacun de vos onglets. Appelons-le TabType . Créez maintenant une variable d'instance tabStacks de type HashMap<TabType, Stack<String>> . Maintenant, vous pouvez instancier une pile pour chaque onglet – chaque pile est une liste de balises, comme spécifié par Fragment.getTag() . De cette façon, vous ne devez pas vous soucier de stocker des références à Fragments et si elles vont disparaître sur vous lorsque vous faites pivoter le périphérique. Chaque fois que vous avez besoin d'une référence à un Fragment , saisissez la bonne étiquette de la pile et utilisez FragmentManager.findFragmentByTag() .

    Maintenant, chaque fois que vous souhaitez pousser un Fragment sur un onglet, générez une nouvelle étiquette (j'ai utilisé UUID.randomUUID().toString() ) et utilisez-le dans votre appel vers FragmentTransaction.add() . Ensuite, appuyez sur l'étiquette sur la pile pour l'onglet affiché actuellement.

    Faites attention: lorsque vous souhaitez repousser un nouveau fragment sur un ancien, ne remove() pas remove() l'ancien, car le FragmentManager va le considérer et ce sera nettoyé. Assurez-vous de detach() il, puis attach() plus tard. N'utilisez que remove() lorsque vous étiez en permanence un Fragment et utilisez uniquement add() la première fois que vous souhaitez le montrer.

    Ensuite, vous devrez ajouter une logique relativement simple à votre TabListener . Lorsqu'un onglet n'est pas sélectionné, il suffit de peek() à sa pile et detatch() le fragment associé. Lorsqu'un onglet est sélectionné, peek() en haut de cette pile et attach() ce fragment.

    Enfin, vous devrez traiter les facettes du cycle de vie de l'activité (comme les changements d'orientation). Persistez votre Map des Stacks ainsi que l'onglet actuellement sélectionné et décompressez-le à nouveau dans votre onCreate() . (Vous n'obtenez pas ce conditionnement et le déballage gratuitement, mais c'est assez facile à faire.) Heureusement, votre énumération TabType est Serializable donc il devrait être trivial de mettre dans un Bundle .

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.