2013-02-14 7 views
2

J'utilise un FragmentTabHost dans une FragmentActivity, qui a 3 onglets. Si je change d'onglet à partir de la première page de chaque onglet, cela fonctionne bien, mais si je navigue jeter des fragments à l'intérieur d'un onglet, puis changer d'onglet, il montre le nouveau fragment chevauché à l'ancien. Quelqu'un peut m'aider?FragmentTabHost montre des fragments superposés

C'est la mise en page de FragmentActivity (fragments_tab.xml):

<?xml version="1.0" encoding="UTF-8"?> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/relativeLayout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:src="@drawable/background_gradient"> 

    <ImageView 
     android:contentDescription="@string/app_name" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_alignParentBottom="true" 
     android:layout_alignParentLeft="true" 
     android:src="@drawable/background_gradient" /> 

    <android.support.v4.app.FragmentTabHost 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/tabhost" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <LinearLayout 
     android:orientation="vertical" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <TabWidget 
      android:id="@android:id/tabs" 
      android:orientation="horizontal" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_weight="0"/> 

     <FrameLayout 
      android:id="@android:id/tabcontent" 
      android:layout_width="0dp" 
      android:layout_height="0dp" 
      android:layout_weight="0"/> 

     <LinearLayout 
      android:id="@+id/realtabcontent" 
      android:layout_width="match_parent" 
      android:layout_height="0dp" 
      android:layout_weight="1"/> 

    </LinearLayout> 
    </android.support.v4.app.FragmentTabHost> 
    </RelativeLayout> 

Mon code de FragmentActivity:

public class MainActivity extends FragmentActivity { 

     private FragmentTabHost mTabHost; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setDB(); 
      setContentView(R.layout.fragments_tab); 

      mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost); 

      mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); 


      mTabHost.addTab(mTabHost.newTabSpec("Home").setIndicator("Home",  getResources().getDrawable(R.drawable.ic_menu_home)), 
        HomeFragment.class, null); 

      mTabHost.addTab(mTabHost.newTabSpec("Map").setIndicator("Map", getResources().getDrawable(R.drawable.ic_menu_mapmode)), 
        MapMenuFragment.class, null); 
      mTabHost.addTab(mTabHost.newTabSpec("Info").setIndicator("Info", getResources().getDrawable(R.drawable.ic_menu_info_details)), 
        InfoFragment.class, null); 
     } 
} 

Chaque fragment est créé pour:

public class InfoFragment extends Fragment { 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) 
    { 
     super.onActivityCreated(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     View view = inflater.inflate(R.layout.fragment_info, container, false); 
     return view; 
    } 

Quelqu'un peut-il aider moi s'il vous plait?

Répondre

0

J'ai effectivement eu un problème similaire à cela. Je sélectionnais des éléments dans un ListFragment et ensuite créer un nouveau fragment et remplacer le fragment de liste d'origine dans la disposition de l'onglet. J'ai découvert que lorsque je passais à d'autres onglets, il y avait plusieurs fragments montrant en même temps, se chevauchant, ou j'avais des fragments qui devaient disparaître. Ma solution était de dégager la pile de retour lorsqu'un nouvel onglet a été sélectionné, essayez d'ajouter ce code à votre méthode onTabSelected() dans votre TabListener

FragmentManager manager = getSupportFragmentManager(); 

    if(manager.getBackStackEntryCount() > 0) 
    { 
     manager.popBackStack(null, 
          FragmentManager.POP_BACK_STACK_INCLUSIVE); 
    } 

Faire cela a résolu le problème pour moi.

+0

Merci pour la réponse @WingedRayeth, mais je pense que votre solution que vous allez nettoyer la pile chaque fois que vous changez onglet. Ainsi, par exemple, si vous naviguez dans le premier onglet jusqu'au quatrième fragment, puis changez d'onglet, lorsque vous revenez au premier onglet, vous recommencez à partir du premier fragment. J'ai finalement trouvé une solution, je vais expliquer ci-dessous – al1812

1

J'ai trouvé une solution à ma question. Dans mon projet, chaque fragment est une classe différente qui étend la classe Fragment. Lorsque FragmentTabHost a tenté de détacher l'ancien fragment, il n'a pas pu trouver d'objet Fragment et n'a donc rien supprimé. Je ne suis pas si expert, je suis sûr qu'il y a un moyen plus simple, mais après beaucoup de maux de tête j'ai trouvé cette solution qui fonctionne. C'est ce que j'ai fait:

  • J'ai enregistré le fragment actuel pour chaque onglet dans la variable Objet de l'activité.
  • J'ai copié le code de FragmentTabHost dans sa propre classe et j'ai changé la méthode doTabChanged lorsque l'appel s'est détaché ou attaché.

(j'ai 3 onglets "Home", "Carte" et "Info")

Détacher:

//ft.detach(mLastTab.fragment); 
if(mLastTab.tag == "Home") ft.detach((Fragment) tabHomeFragment); 
else if(mLastTab.tag == "Info") ft.detach((Fragment) tabInfoFragment); 
else ft.detach((Fragment) tabMapFragment); 

attach:

//ft.attach(newTab.fragment); 
if(newTab.tag == "Home") ft.attach((Fragment) tabHomeFragment); 
else if(newTab.tag == "Info") ft.attach((Fragment) tabInfoFragment); 
else ft.attach((Fragment) tabMapFragment); 

tabHomeFragment, tabMapFragment et tabInfoFragment contient les fragments actuels pour chaque onglet

0

Le problème est survenu parce que TabHost ne peut pas gérer correctement le fragment que vous avez ajouté.

J'ai jamais rencontré le même problème et résolu par le modèle de conteneur de fragmentation. FragmentContainer est une classe auto-définie qui s'étend à partir de Fragment.

Vous pouvez init chaque onglet avec un conteneur.Chaque conteneur gère son propre fragment enfant à l'aide de getChildFragmentManager(). Vous pouvez ajouter, remplacer, enlever n'importe quoi comme vous voulez.

Lorsque Tab est modifié, le conteneur est également commuté, il n'y a pas de problème de chevauchement.

Voici un simple conteneur jamais je writted: https://stackoverflow.com/a/15903349/1695108

0

J'ai rencontré la même situation et ce qui suit a fonctionné pour moi.

Vérifiez si le saveInstanceState sinon null, dans ce cas, ne fait pas la transaction de fragment. Cela va résoudre ce problème.

if (homeFragment == null) { 
    if (savedStateInstance != null) { 
    homeFragment = (HomeFragment) fragmentManager.findFragmentByTag(HOME_FRAGMENT); 
    return; 
} 
// tie new fragment 
homeFragment = new HomeFragment(); 
homeFragment.setArguments(bundle); 
FragmentTransaction transaction = fragmentManager.beginTransaction(); 
transaction.add(homeFragment, HOME_FRAGMENT); 
transaction.commit(); 
} 

Espérons que cela aide.

1

Je sais que c'est une question assez ancienne, mais je vais fournir ma solution de toute façon, donc il peut être utile à quiconque va lire cette question. J'ai eu le même problème, et je compris que le problème a été causé en appelant

mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); 

parce que faire cet appel, le tabhost sera inizialize ce FrameLayout avec tous les fragments spécifiés dans mTabHost.addTab méthode

Je résolu mon problème appelant

mTabHost.setup(this, getSupportFragmentManager(), R.id.tabcontent); 

de cette façon, la FrameLayout R.id.tabcontent sera caché (width = 0, height = 0), et que, la mise en œuvre OnTabChangeListener, vous pouvez tout simplement faire

@Override 
    public void onTabChanged(String tabId) { 
     FragmentTransaction t = getSupportFragmentManager().beginTransaction(); 
     if (tabId.equals(Frament1.TAG)) { 
      t.replace(R.id.realtabcontent, Fragment1.newInstance()); 
     } else if (tabId.equals(Frament2.TAG)) { 
      t.replace(R.id.realtabcontent, Fragment2.newInstance()); 
     } else if (tabId.equals(Frament3.TAG)) { 
      t.replace(R.id.realtabcontent, Fragment3.newInstance()); 
     } 
     //optional 
     t.addTobackStack(); 

     t.commit() 
    } 

il devrait fonctionner

Questions connexes