Android - Définir l'ID de fragment

111

Comment puis - je mettre un Fragment« s Idpour que je puisse utiliser getSupportFragmentManager().findFragmentById(R.id.--)?

tyb
la source
Vous pouvez le définir dans un fichier xml de mise en page
Vladimir Eremeev

Réponses:

117

Vous ne pouvez pas définir l'ID d'un fragment par programme .

Il existe cependant un String tagque vous pouvez définir dans FragmentTransaction qui peut être utilisé pour identifier de manière unique un Fragment.

Comme l'a souligné Aleksey, vous pouvez transmettre un identifiant à FragmentTransactionla add(int, Fragment)méthode de. Cependant, cela ne spécifie pas l'ID d'un fragment. Il spécifie l'ID de a ViewGroupdans lequel insérer Fragment. Ce n'est pas très utile pour le but que j'attends de vous, car il n'identifie pas de façon unique les Fragments, mais l' ViewGroupart. Ces ID sont des conteneurs auxquels un ou plusieurs fragments peuvent être ajoutés dynamiquement. L'utilisation d'une telle méthode pour identifier les Fragments vous obligerait à ajouter des ViewGroups dynamiquement à la mise en page pour chaque Fragmentinsertion. Ce serait assez fastidieux.

Donc , si votre question est de savoir comment créer un identifiant unique pour un fragment que vous ajoutez dynamiquement, la réponse est d'utiliser FragmentTransaction« de l'add (int containerViewId, Fragment fragment, étiquette String) méthode et FragmentManager» de findFragmentByTag (String) méthode.

Dans l'une de mes applications, j'ai été obligé de générer des chaînes de manière dynamique. Mais ce n'est pas si cher que la FragmentTransaction réelle, de toute façon.

Un autre avantage de la méthode de balise est qu'elle peut identifier un fragment qui n'est pas ajouté à l'interface utilisateur. Consultez la méthode add (Fragment, String) de FragmentTransaction . Fragments n'a pas besoin de Views! Ils peuvent également être utilisés pour conserver l'état éphémère entre les changements de configuration!

Thomas Dignan
la source
Si j'utilise la balise et non l'ID du fragment, comment utiliser l'appel de remplacement qui nécessite un ID de ressource de fragment?
Namratha
12
@TomDignan que diriez-vous d'un fragment qui sera ajouté dans un ViewPager? Comment puis-je définir son tag? Je ne peux pas utiliser de transactions dans cette situation.
GuilhE
1
@GuilhE Activity fournit une méthode addFragment () que vous pouvez référencer à partir du viewpager. Garder la balise avant cela pourrait être accompli avec un hashmap.
Thomas Dignan
1
La réponse peut-elle être modifiée un peu pour souligner que vous pouvez définir un identifiant dans une mise en page XML? Parce que personnellement, je n'ai pas lu d'autres questions et j'avais l'impression qu'il n'y avait aucun moyen de définir l'identifiant du fragment ...
Ivan
41

Il s'avère que vous n'avez peut-être pas besoin de connaître l'ID du fragment.

À partir de la documentation:

public abstract Fragment findFragmentById (int id)

Finds a fragment that was identified by the given id either
when inflated from XML or as the container ID when added in
a transaction.

La partie importante est «comme ID de conteneur lorsqu'il est ajouté dans une transaction».

alors:

getSupportFragmentManager()
    .beginTransaction()
    .add(R.id.fragment_holder, new AwesomeFragment())
    .commit();

puis

AwesomeFragment awesome = (AwesomeFragment)
     getSupportFragmentManager()
          .findFragmentById(R.id.fragment_holder);

vous obtiendrez le fragment (génial) contenu dans R.id.fragment_holder.

Morale de l'orignal
la source
4

Dans la plupart des cas, vous pouvez utiliser la balise de fragment ainsi que l'ID.
Vous pouvez définir la valeur de la balise dans FragmentTransaction.add(Fragment fragment, String tag );. Ensuite, vous pouvez utiliser la commande FragmentManager.findFragmentByTag(String tab)pour trouver le fragment en question.

utilisateur2014118
la source
2

Comme Tom et d'autres l'ont déjà mentionné, il existe des moyens de mettre une étiquette sur un fragment et d'utiliser cette étiquette pour l'identification. Un problème ultérieur que j'ai rencontré avec ces solutions est que le fragment ne reçoit pas de balise tant qu'il n'est pas associé à l'activité (ou, en fait, à la FragmentManager). Que faire si l'on a besoin d'identifier un fragment avant qu'il n'ait été étiqueté?

Jusqu'à présent, mes solutions reposent toutes sur la plus ancienne astuce (Java) au monde: créer un fragment de modèle minimaliste qui prend un identifiant dans l'un de ses constructeurs et fournit une getFragmentId()méthode qui renvoie cet identifiant. Je laisse ensuite ces fragments qui nécessitent une identification précoce étendre ce modèle et; voila! Problème résolu.

Cette solution pourrait, malheureusement, nécessiter un ensemble de fragments de modèle, un pour chaque type de fragment ListFragment, DialogFragmentou tout simplement ancien Fragment(POFO?!) Qui nécessitent une identification précoce. Mais c'est gérable dans le cas de fragments je pense, compte tenu des gains apportés.

Désolé d'avoir déchiré des plaies cicatrisantes :-)

À votre santé!

dbm
la source
0

Utilisez le suivant:

Pour ajouter un fragment:

getFragmentManager().beginTransaction().add(R.id.fragment_container, fragmentToBeAdded, tag).commit();

Pour identifier le fragment existant:

getFragmentManager().findFragmentByTag(fragmentName);
Jaydev
la source
La réponse n'est pas pertinente pour la question. Veuillez mettre à jour la réponse. Happy Coding
CodeWithVikas
-1

Lorsque vous utilisez une balise, assurez-vous d'ajouter le

fragmentTransaction.addToBackStack(null); 

afin que votre Fragment soit repris au lieu d'être détruit comme indiqué dans les guides du développeur.

Si vous n'appelez pas addToBackStack () lorsque vous effectuez une transaction qui supprime un fragment, ce fragment est détruit lorsque la transaction est validée et l'utilisateur ne peut pas y revenir. Alors que, si vous appelez addToBackStack () lors de la suppression d'un fragment, le fragment est arrêté et est repris ultérieurement si l'utilisateur revient en arrière.

Vous pouvez le trouver à la fin de cette page .

J'ai perdu environ 30 minutes à essayer de comprendre pourquoi mon Fragment n'a pas été trouvé par un simple findFragmentByTag();appel

Panos Gr
la source
-2

En plus de la réponse de Tom, la méthode replace prend également en charge la balise fragment, en plus de la méthode add.

oren zvi
la source