15

Dans mon application, j'utilise un Activity qui contient un Fragment avec FragmentTabHost et par conséquent tous ses onglets sont nested Fragments.Obtenir une référence au fragment imbriqué de FragmentTabHost

À l'intérieur d'un Activity qui détient un Fragment avec son nested Fragment, nous pouvons obtenir une référence à l'un en utilisant onAttachedFragment(). Mais comment obtenir une référence à nested Fragment de FragmentTabHost?

Répondre

24

Eh bien, en explorant le code source de FragmentTabHost J'ai trouvé que quand il ajoute un onglet de fragment, il assigne un tag de TabSpec à Fragment imbriqué.

Donc, pour obtenir la référence à cette Fragment nous devrions appeler

getChildFragmentManager().findFragmentByTag(tabSpecTag)

+1

pouvez-vous s'il vous plaît poster le code où faites-vous exactement la cartographie parce que je reçois toujours NullPointerException sur ma référence – Ravi

+1

@Ravi, j'ai ajouté ce code dans mon fragment onActivityCreated() méthode là je me réfère à ce fragment – DavyJonesUA

+0

Vous appelez getChildFragmentManager() sur quel objet? – Cozzamara

6

Je tentais pendant un certain temps, mais je recevais null est revenu de la FragmentManager parce que je tente d'accéder au gestionnaire de onCreateView() immédiatement après l'ajout.

Here is a good explanation on what happened

Il est également important de noter que Fragment onglets qui n'ont pas encore été sélectionnés ne FragmentManager, et ainsi n'existe pas encore dans le retour null aussi bien. J'ai contourné cela en appelant mTabHost.setCurrentTab(index) avant d'essayer d'obtenir le Fragment avec le FragmentManager. Ce n'est pas très propre, mais ça marche.

+0

Eh bien, j'obtiens une référence au 'Fragment 'imbriqué dans' onViewCreated() 'à le début du cycle de vie de 'Fragment' parent, vérifiant si bundle' savedInstanceState' est null - dans ce cas, je sais quel 'Fragment' devrait apparaître par défaut et utiliser la balise spécifique, dans les autres cas j'obtiens une valeur' int' de ce bundle qui représente l'onglet coché que j'ai sauvegardé avant et l'utilise pour faire du casting à une classe de fragment spécifique. J'attribue également une référence de tabulation imbriquée à 'OnTabChangeListener' en utilisant la balise' TabSpec' transmise à la méthode 'onTabChanged()'. –

1

solutions ci-dessus travaillent aussi mais j'ai une solution plus facile,

@Override 
public void onTabChanged(final String tabId) { 

    new Handler().postDelayed(new Runnable() { 
     @Override 
     public void run() { 

      mFragment = getChildFragmentManager().findFragmentByTag("Tagname"); 
     } 
    },1000); 
} 

Ici, vous devez mettre en œuvre FragmentTabHost.onTabChangeListener Nous avons gardé un deuxième retard dans la récupération du fragment childFragmentManager.

Remarque: Vous devez lancer mFragment quel fragment vous avez utilisé.

+1

Une chose que je vois au moins comme un inconvénient est que vous faites une fuite de mémoire potentielle en allouant de la mémoire pour un objet '' 'Handler''' anonyme. Après avoir été invoqué, il garde la référence à la classe externe environ une seconde. Donc, si vous quittez votre activité juste après avoir changé un onglet, vous aurez toujours une référence en mémoire. Vous devriez réfléchir à deux fois si vous invoquez ce code dans la classe '' '' Activity'''. De plus, si l'utilisateur décide de jouer avec vos onglets et de les balayer au hasard, alors vous remplissez votre file d'attente avec '' 'Runnable''s et il n'y a aucun moyen de les retirer de' '' Handler''' –

+0

D'accord avec vous mais je voudrais obtenir l'emplacement approprié d'où appeler cette méthode mFragment = getChildFragmentManager(). findFragmentByTag ("Tagname"); ... C'est le code où j'ai trouvé la solution. Merci pour votre avis profond :) –

1

J'ai trouvé une solution que j'aime un peu mieux car elle n'implique pas l'exécution de code avec un retard (ce qui est toujours incertain étant donné la fragmentation matérielle android et les différentes vitesses du processeur).

Dans votre méthode onTabChanged(), avant d'essayer de trouver le fragment, appelez executePendingTransactions() sur le gestionnaire de fragments associé à votre tabHost. Il semble qu'il y ait des endroits dans le code source de FragmentTabHost où ils devraient appeler executePendingTransactions() mais ne parviennent pas à le faire.

Cela fonctionne chaque fois que l'onglet change à une exception près ... le premier onglet sélectionné est toujours nul ... Dans mon cas spécifique, j'ai pu gérer cette exception de toute façon, en mettant du code pour résumer.

Espérons que cela aide.

Questions connexes