web-dev-qa-db-fra.com

Android - Définir l'identifiant du fragment

Comment définir une Fragment 's Id pour pouvoir utiliser getSupportFragmentManager().findFragmentById(R.id.--)?

102
tyb

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

Cependant, il existe un String tag que vous pouvez définir dans FragmentTransaction et qui peut être utilisé pour identifier de manière unique un fragment.

Comme Aleksey l'a souligné, vous pouvez transmettre un ID à la méthode FragmentTransaction de add(int, Fragment). Cependant, cela ne spécifie pas l'ID d'un fragment. Il spécifie l'ID d'une ViewGroup dans laquelle insérer la Fragment. Ce n’est pas très utile pour le but que vous vous attendez, car cela n’identifie pas uniquement Fragments, mais ViewGroups. Ces ID sont de conteneurs auxquels un ou plus fragments peuvent être ajoutés de manière dynamique. L'utilisation d'une telle méthode pour identifier Fragments nécessiterait que vous ajoutiez ViewGroups de manière dynamique à la mise en page pour chaque Fragment que vous insérez. Ce serait assez lourd.

Donc, si votre question est de savoir comment créer un identifiant unique pour un fragment que vous ajoutez de manière dynamique, la solution consiste à utiliser FragmentTransaction 's add (int conteneurViewId, fragment de fragment, balise String) method et FragmentManager's 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 par rapport à 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’a pas été ajouté à l’UI. Voir la méthode add de FragmentTransaction (Fragment, String) . Fragments n'a pas besoin d'avoir Views! Ils peuvent également être utilisés pour conserver un état éphémère entre les changements de configuration!

107
Thomas Dignan

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

De la docs:

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 "en tant qu'ID de conteneur lorsqu'il est ajouté dans une transaction".

alors:

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

et alors

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

vous obtiendrez tout ce qui est (génial) dans R.id.fragment_holder.

38
Moose Morals

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

4
user2014118

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 s'il faut identifier un fragment avant qu'il ait été étiqueté?

Jusqu'à présent, mes solutions reposent toutes sur la plus ancienne astuce (Java) du monde: créer un fragment de modèle minimaliste prenant un identifiant dans l'un de ses constructeurs et fournissant une méthode getFragmentId() qui le renvoie. J'ai ensuite laissé les fragments nécessitant une identification précoce étendre ce modèle; le tour est joué! Problème résolu.

Malheureusement, cette solution peut nécessiter un ensemble de fragments de modèle, un pour chaque type de fragment, ListFragment, DialogFragment ou plain old Fragment (POFO?!) Qui nécessitent une identification précoce. Mais je pense que cela est gérable dans le cas de fragments, compte tenu des gains obtenus.

Désolé de déchirer les plaies de guérison :-)

À votre santé!

2
dbm

Utilisez le suivant:

Pour ajouter un fragment: 

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

Pour identifier un fragment existant:

getFragmentManager().findFragmentByTag(fragmentName);
1
Jaydev

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. 

0
oren zvi

Lorsque vous utilisez un tag, assurez-vous d’ajouter le 

fragmentTransaction.addToBackStack(null); 

méthode afin que votre fragment soit repris au lieu de 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 que l'utilisateur ne peut pas y revenir. Par contre, si vous appelez addToBackStack () lors de la suppression d'un fragment, celui-ci est arrêté et 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é retrouvé par un simple appel findFragmentByTag();

0
Panos Gr