251 votes

Que signifie le paramètre LayoutInflater attachToRoot ?

Le site LayoutInflater.inflate La documentation n'est pas très claire pour moi quant à l'objectif de l'outil de gestion de l'information. attachToRoot paramètre.

attachToRoot : si la hiérarchie gonflée doit être attachée au paramètre Root ? Si la réponse est non, Root est uniquement utilisé pour créer la sous-classe de LayoutParams pour la vue Root dans le XML.

Quelqu'un pourrait-il expliquer plus en détail, notamment ce qu'est la vue Racine, et peut-être montrer un exemple de changement de comportement entre des valeurs vraies et fausses ?

1 votes

0 votes

99voto

Joseph Earl Points 11953

Si elle est définie sur true, lorsque votre mise en page est gonflée, elle sera automatiquement ajoutée à la hiérarchie de vue du ViewGroup spécifié dans le second paramètre en tant qu'enfant. Par exemple, si le paramètre Root est un LinearLayout alors votre vue gonflée sera automatiquement ajoutée comme enfant de cette vue.

S'il est défini à false, votre mise en page sera gonflée mais ne sera pas attachée à une autre mise en page (elle ne sera donc pas dessinée, ne recevra pas d'événements tactiles, etc.)

17 votes

Je suis confus. J'obtenais un message d'erreur "Specified child already has a parent error" jusqu'à ce que je lise cette réponse qui m'a demandé d'utiliser false para attachToRoot pendant que mon Fragment onCreateView . Cela a résolu le problème et pourtant la disposition du fragment est visible et active, malgré votre réponse. Qu'est-ce qui se passe ici ?

69 votes

Parce qu'un Fragment attache automatiquement la mise en page renvoyée par onCreateView. Donc, si vous l'attachez manuellement dans onCreateView, votre vue est attachée à deux parents (ce qui produit l'erreur que vous mentionnez).

12 votes

Je suis un peu confus ici, @JosephEarl vous avez dit que si l'on règle sur true la vue est attachée au second paramètre qui est le nom de la vue. container mais ensuite vous dites que le fragment est automatiquement attaché à partir de onCreateView() Donc, à mon avis, le troisième paramètre est inutile et doit être défini comme suit false toujours ?

41voto

Martin Cazares Points 4881

Il semble qu'il y ait beaucoup de texte dans les réponses mais pas de code, c'est pourquoi j'ai décidé de relancer cette vieille question avec un exemple de code, dans plusieurs réponses que les gens ont mentionnées :

Si elle est définie sur true, lorsque votre mise en page est gonflée, elle sera automatiquement ajoutée à la hiérarchie de vue du ViewGroup spécifié dans le second paramètre en tant qu'enfant.

Ce que cela signifie réellement en code (ce que la plupart des programmeurs comprennent) est :

public class MyCustomLayout extends LinearLayout {
    public MyCustomLayout(Context context) {
        super(context);
        // Inflate the view from the layout resource and pass it as child of mine.
        LayoutInflater.from(context).inflate(R.layout.child_view, this, true);
    }

}

Remarquez que le code précédent ajoute le layout "R.layout.child_view" en tant qu'enfant de MyCustomLayout parce que le paramètre attachToRoot est vrai et attribue les paramètres de layout du parent exactement de la même manière que si j'utilisais "addView" de manière programmatique, le code suivant explique le scénario lorsque le paramètre attachRoot est faux :

LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
linearLayout.setOrientation(LinearLayout.VERTICAL);
    //Create a stand-alone view
View myView = LayoutInflater.from(context).inflate(R.layout.ownRootView, null, false);
linearLayout.addView(myView);

Dans le code précédent, vous avez spécifié que vous vouliez que "myView" soit son propre objet racine et que vous ne l'attachiez à aucun parent. Plus tard, nous l'avons ajouté comme partie intégrante du LinearLayout, mais pendant un moment, c'était une vue autonome (sans parent).

La même chose se produit avec les fragments, vous pouvez les ajouter à un groupe déjà existant et en faire partie, ou simplement passer les paramètres :

inflater.inflate(R.layout.fragment, null, false) ;

Pour préciser qu'il s'agira de sa propre racine.

J'espère que cela vous aidera...

Salutations !

1 votes

De tous, c'est celui qui a été le plus utile.

27voto

Luksprog Points 52767

La documentation et les deux réponses précédentes devraient suffire, c'est juste une réflexion de ma part.

Le site inflate est utilisée pour gonfler les fichiers de mise en page. Avec ces mises en page gonflées, vous avez la possibilité de les attacher directement à un parent. ViewGroup ou simplement gonfler la hiérarchie de vue à partir de ce fichier de mise en page et travailler avec elle en dehors de la hiérarchie de vue normale.

Dans le premier cas, le attachToRoot devra être réglé sur true (ou tout simplement utiliser le inflate qui prend un fichier de mise en page et un Root parent. ViewGroup (non null )). Dans ce cas, le View retourné est simplement le ViewGroup qui a été transmis dans la méthode, le ViewGroup à laquelle la hiérarchie de vue gonflée sera ajoutée.

Pour la deuxième option, le retour View est la racine ViewGroup à partir du fichier de mise en page. Si vous vous souvenez de notre dernière discussion du include-merge question de couple c'est l'une des raisons de la merge (lorsqu'un fichier de mise en page avec merge comme Root est gonflé, vous devez fournir un parent et un attachedToRoot doit être réglé sur true ). Si vous aviez un fichier de mise en page avec la racine a merge et attachedToRoot a été fixé à false alors le inflate n'aura rien à retourner comme merge n'a pas d'équivalent. De plus, comme le dit la documentation, le inflate version avec attachToRoot réglé sur false est important parce que vous pouvez créer la hiérarchie de vue avec la correcte LayoutParams du parent. Ceci est important dans certains cas, notamment avec les enfants de AdapterView une sous-classe de ViewGroup pour lequel l addView() L'ensemble de méthodes n'est pas pris en charge. Je suis sûr que vous vous souvenez d'avoir utilisé cette ligne dans la version getView() méthode :

convertView = inflater.inflate(R.layout.row_layout, parent, false);

Cette ligne permet de s'assurer que les R.layout.row_layout a le bon LayoutParams de la AdapterView sur sa racine ViewGroup . Si vous ne le faisiez pas, vous pourriez avoir des problèmes avec le fichier de mise en page si la racine était une RelativeLayout . Le site TableLayout/TableRow ont également des caractéristiques spéciales et importantes LayoutParams et vous devez vous assurer que les vues qu'ils contiennent ont le bon LayoutParams .

21voto

Umer Farooq Points 3368

Moi-même, je ne savais pas non plus quel était le but réel de attachToRoot sur inflate méthode. Après un peu d'étude de l'assurance-chômage, j'ai finalement trouvé la réponse :

parent :

dans ce cas, il s'agit du widget/layout qui entoure les objets de vue que vous souhaitez gonfler à l'aide de findViewById().

attachToRoot :

attache les vues à leur parent (les inclut dans la hiérarchie des parents), donc tout événement tactile que les vues reçoivent sera également transféré à la vue parent. Maintenant, c'est au parent de décider s'il veut recevoir ces événements ou les ignorer. Si la valeur est false, les vues ne sont pas ajoutées en tant qu'enfants directs du parent et le parent ne reçoit pas d'événements de contact de la part des vues.

J'espère que cela clarifie la confusion

0 votes

Votre réponse est déjà fournie ici : stackoverflow.com/questions/22326314/

0voto

CaseyB Points 16014

Lorsque vous définissez le parent, l'option attachToRoot détermine si vous souhaitez que l'inflateur l'attache réellement au parent ou non. Dans certains cas, cela pose des problèmes, comme dans un ListAdapter, cela provoquera une exception parce que la liste tente d'ajouter la vue à la liste, mais elle dit qu'elle est déjà attachée. Dans d'autres cas, lorsque vous gonflez vous-même la vue pour l'ajouter à une activité, cela peut être pratique et vous faire gagner une ligne de code.

1 votes

Ne donne pas une image claire qu'une bonne réponse devrait fournir.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X