web-dev-qa-db-fra.com

Que dois-je passer pour root lors du gonflage d'une mise en page à utiliser pour un MenuItem ActionView?

J'ai un ImageView que j'attache à un MenuItem comme son ActionView (l'élément apparaît dans le ActionBar). La disposition de cette vue provient de XML. Je le gonfle comme ça:

ImageView actionView = (ImageView) layoutInflater.inflate(
   R.layout.action_view_layout, null);

Cela semble bien fonctionner. Pourtant; passer null pour root dans l'appel à inflate() me fait crier Lint:

Évitez de passer null comme racine de la vue (besoin de résoudre les paramètres de mise en page sur l'élément racine de la mise en page gonflée)

Je peux apparemment gérer sans racine dans mon cas spécifique, mais je préfère que le code soit aussi correct que possible. Le problème est que je ne sais pas quel View doit être utilisé comme racine ici. Cette réponse indique que ce devrait être "le widget qui entoure les objets de vue que vous souhaitez gonfler". Mais qu'est-ce que cela signifie ici? Celui pour la barre d'action? L'activité? Quelque chose d'autre entièrement?


Mise à jour: La lecture des réponses m'a fait soupçonner que la bonne chose à faire est:

  1. Récupère le ActionBarView correspondant au MenuItem
  2. Obtenez sa racine
  3. Convertissez la racine en ViewGroup
  4. Passer le résultat au gonfleur

Cela semble fonctionner. Quelqu'un peut-il confirmer ou infirmer si c'est ce qui devrait être fait?

37
dlf

Je le ferais simplement comme ceci:

menuItem.setActionView(R.layout.action_view_layout);

Laissez Android gonfler la vue pour vous.

Si vous devez apporter des modifications supplémentaires à cet appel ImageView

ImageView imageView = (ImageView) menuItem.getActionView();

Mise à jour

Afin de répondre à votre curiosité. C'est ce que les gens de Google font sous le capot:

public MenuItem setActionView(int resId) {
    final Context context = mMenu.getContext();
    final LayoutInflater inflater = LayoutInflater.from(context);
    setActionView(inflater.inflate(resId, new LinearLayout(context), false));
    return this;
}
24
Damian Petla

Vous avez regardé cela. cela explique aussi bien le gonfleur de mise en page.

Il existe deux versions utilisables de la méthode inflate() pour une application standard:

inflate(int resource, ViewGroup root)
inflate(int resource, ViewGroup root, boolean attachToRoot)

Le premier paramètre pointe vers la ressource de mise en page que vous souhaitez gonfler. Le deuxième paramètre est la vue racine de la hiérarchie à laquelle vous gonflez la ressource à attacher. Lorsque le troisième paramètre est présent, il détermine si la vue gonflée est attachée ou non à la racine fournie après le gonflage.

Ce sont ces deux derniers paramètres qui peuvent créer un peu de confusion. Avec la version à deux paramètres de cette méthode, LayoutInflater tentera automatiquement d'attacher la vue gonflée à la racine fournie. Cependant, le framework vérifie que si vous passez null pour la racine, il contourne cette tentative pour éviter un plantage de l'application.

De nombreux développeurs considèrent que ce comportement signifie que la bonne façon de désactiver l'attachement lors du gonflage consiste à passer null en tant que root; dans de nombreux cas, ne réalisant même pas que la version à trois paramètres de inflate () existe.

En savoir plus sur l'inflation de la mise en page

12
Top Cat

Vous voulez généralement passer ce que vous voulez (sous-classe ViewGroup) auquel vous allez ajouter actionView pour le gonfler. afin de récupérer actionView de l'appel de gonflement et non du parent, vous voudrez ajouter un 3e paramètre, false, afin qu'il n'ajoute pas la vue gonflée au parent.

ImageView actionView = 
    (ImageView)layoutInflater.inflate(R.layout.action_view_layout, parent, false);
// .. do whatever you like with actionView and then add it to it's parent
menuItem.addActionView(actionView)

Il y a un très bon tutoriel ici qui aborde les choses un peu différemment. Il spécifie action_view_layout dans le cadre de menu.xml avec quelque chose comme:

Android:actionLayout="@layout/action_view_layout"

Cela peut également fonctionner pour vous à condition d'utiliser toujours la même mise en page. si vous suivez cette route, vous pourrez obtenir le ActionView en faisant

ImageView actionView = menu.findItem(R.id.whatever).getActionView();
3
user2399268