wake-up-neo.com

Was soll ich als root übergeben, wenn ich ein Layout aufblase, das für eine MenuItem ActionView verwendet werden soll?

Ich habe ein ImageView, das ich einem MenuItem als sein ActionView anhänge (der Gegenstand erscheint im ActionBar). Das Layout für diese Ansicht stammt aus XML. Ich blase es so auf:

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

Dies scheint gut zu funktionieren. Jedoch; Die Übergabe von null für root im Aufruf an inflate() bringt Lint dazu, mich anzuschreien:

Vermeiden Sie die Übergabe von null als Ansichtsstamm (es müssen Layoutparameter für das Stammelement des aufgeblasenen Layouts aufgelöst werden).

In meinem speziellen Fall kann ich anscheinend ohne Root auskommen, aber ich möchte lieber, dass der Code so korrekt wie möglich ist. Das Problem ist, ich bin nicht sicher, welches View hier als Root verwendet werden soll. Diese Antwort sagt, es sollte "das Widget sein, das die Ansichtsobjekte umgibt, die Sie aufblasen möchten." Aber was heißt das hier? Die für die Aktionsleiste? Die Aktivität? Noch etwas ganz anderes?


Update: Als ich die Antworten gelesen habe, habe ich den Verdacht, dass Folgendes richtig ist:

  1. Holen Sie sich das ActionBarView, das dem MenuItem entspricht
  2. Holen Sie sich seine Wurzel
  3. Wirf die Wurzel in ein ViewGroup
  4. Leiten Sie das Ergebnis an den Inflater weiter

Das scheint zu funktionieren. Kann jemand bestätigen oder leugnen, ob dies getan werden sollte?

37
dlf

Ich würde es einfach so machen:

menuItem.setActionView(R.layout.action_view_layout);

Lassen Sie Android die Ansicht für Sie aufblasen.

Wenn Sie zusätzliche Änderungen an diesem ImageView-Aufruf vornehmen müssen

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

pdate

Um Ihrer Neugier gerecht zu werden. Das tun Leute von Google unter der Haube:

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

Sie haben darauf geschaut. es erklärt auch den Layout Inflator.

Es gibt zwei verwendbare Versionen der inflate() -Methode für eine Standardanwendung:

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

Der erste Parameter zeigt auf die Layoutressource, die Sie aufblasen möchten. Der zweite Parameter ist die Stammansicht der Hierarchie, mit der Sie die anzuhängende Ressource aufblasen. Wenn der dritte Parameter vorhanden ist, wird festgelegt, ob die aufgeblasene Ansicht nach dem Aufblasen an die angegebene Wurzel angehängt wird.

Es sind die letzten beiden Parameter, die zu Verwirrung führen können. Bei der Zwei-Parameter-Version dieser Methode versucht LayoutInflater automatisch, die aufgeblasene Ansicht an die angegebene Wurzel anzuhängen. Das Framework verfügt jedoch über eine Überprüfung, die diesen Versuch umgeht, um einen Anwendungsabsturz zu vermeiden, wenn Sie für den Stamm null übergeben.

Unter diesem Verhalten verstehen viele Entwickler, dass die ordnungsgemäße Deaktivierung des Anhangs bei Inflation darin besteht, null als root zu übergeben. In vielen Fällen wird nicht einmal bemerkt, dass die Drei-Parameter-Version von inflate () existiert.

Mehr zum Thema Layout Inflation

12
Top Cat

Sie möchten im Allgemeinen die ViewGroup-Unterklasse übergeben, der Sie zum Aufblasen actionView hinzufügen möchten. Um actionView vom Aufruf inflate und nicht vom übergeordneten Element zurück zu erhalten, müssen Sie einen dritten Parameter (false) hinzufügen, damit die aufgeblasene Ansicht nicht zum übergeordneten Element hinzugefügt wird.

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)

Es gibt ein ziemlich gutes Tutorial hier , das die Dinge ein wenig anders angeht. Es spezifiziert action_view_layout im Rahmen menu.xml mit so etwas wie:

Android:actionLayout="@layout/action_view_layout"

Dies funktioniert möglicherweise auch bei Ihnen, sofern Sie immer dasselbe Layout verwenden. Wenn Sie diesen Weg gehen, können Sie auf diese Weise ActionView erhalten

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