2014-05-24 19 views
33

Ich habe eine ImageView, die ich an eine MenuItem als ActionView (der Artikel erscheint in der ActionBar) anhängen. Das Layout für diese Ansicht stammt aus XML. Ich blase es so auf:Was soll ich für root übergeben, wenn ich ein Layout für die ActionView eines MenuItems aufblase?

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

Dies scheint gut zu funktionieren. Jedoch; null für root in dem Aufruf von inflate() vorbei macht Lint schreien mich an:

vermeiden wie die Ansicht root null vorbei (müssen Layout Parameter auf den aufgeblasenen Layout des Wurzelelement lösen)

ich kann scheinbar ohne Root in meinem speziellen Fall, aber ich würde lieber den Code so korrekt wie möglich haben. Das Problem ist, ich bin mir nicht sicher, welche View als Root hier verwendet werden sollte. This answer sagt, es sollte "das Widget sein, das die Ansichtsobjekte umgibt, die Sie aufblasen möchten." Aber was heißt das hier? Der für die Aktionsleiste? Die Aktivität? Etwas ganz anderes?


Update: die Antworten Lesen hat mich mich vermuten, dass das Richtige zu tun ist:

  1. die ActionBarView zum MenuItem
  2. entsprechenden Erhalten seiner Wurzel
  3. Cast Holen Sie sich das Wurzel zu einem ViewGroup
  4. Übergeben Sie das Ergebnis an den Inflatter

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

+7

gibt es einen ausgezeichneten Artikel über diese: http://www.doubleencore.com/2013/05/layout-inflation-as-intended/ (dh in Bezug auf Inflation, nicht in Bezug auf die Frage selbst) –

Antwort

24

ich tun würde, es einfach so:

menuItem.setActionView(R.layout.action_view_layout); 

Let Android aufblasen die Ansicht für Sie.

Wenn Sie zusätzliche Änderungen an diesem Image Anruf

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

aktualisieren

Um tun müssen, um Ihre Neugier zu befriedigen. Das ist, was die Leute von Google unter der Haube tun:

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; 
} 
+0

Nun, meine Güte; Ich wusste nicht einmal, dass Überlastung existiert. Wenn ich es benutze, kann ich das Ergebnis der Inflation nicht zwischenspeichern und später wiederverwenden (ich entferne die ActionView mehrfach und befestige sie wieder), aber vielleicht sollte ich das sowieso nicht machen. Und danke, dass du gezeigt hast, was diese Funktion eigentlich macht; Ich schätze, ich habe es komplizierter gemacht, als es sein musste. – dlf

+0

Ich glaube nicht, dass Sie es zwischenspeichern müssen, aber wenn Sie dupts eine andere Frage stellen und Link hier einfügen, so kann ich es verfolgen und Ihnen eine Antwort geben. Vergessen Sie nicht, Ihren Code zu posten. Daumen hoch! –

+0

Ich brauche definitiv * nicht *; Ich dachte nur, ich würde die Kosten für das Aufblasen des Layouts jedes Mal sparen. Aber es ist sicher eine vorzeitige Optimierung. – dlf

3

Im Allgemeinen möchten Sie, was auch immer (ViewGroup-Unterklasse) übergeben wird, dem Sie actionView hinzufügen, um es aufzublasen. Um actionView zurück vom inflate-Aufruf und nicht vom übergeordneten Element zu erhalten, müssen Sie einen dritten Parameter false hinzufügen, damit die überlagerte 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 ist ein ziemlich gutes Tutorial here, die ein wenig anders über die Dinge geht. Es ist die Angabe action_view_layout als Teil menu.xml mit so etwas wie:

android:actionLayout="@layout/action_view_layout" 

das für Sie auch Sie immer das gleiche Layout verwenden bereitgestellt wird, kann arbeiten. wenn Sie diesen Weg gehen würden Sie in der Lage sein, die ActionView auszukommen

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

tun Sie haben Blick auf diese. Das erklärt auch den Layout Inflator.

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

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

Die ersten Parameter zeigen auf die Layout-Ressource Sie aufblasen wollen.Der zweite Parameter ist die Stammansicht der Hierarchie, in der Sie die anzulegende Ressource auffüllen. Wenn der dritte Parameter vorhanden ist, bestimmt er, ob die aufgeblasene Ansicht nach dem Aufblasen an der gelieferten Wurzel befestigt ist oder nicht.

Es sind diese letzten zwei Parameter, die ein wenig Verwirrung verursachen können. Mit der Zwei-Parameter-Version dieser Methode wird LayoutInflater automatisch versuchen, die aufgeblähte Ansicht an die angegebene Wurzel anzuhängen. Das Framework verfügt jedoch über eine Überprüfung, dass der Versuch, einen Anwendungsabsturz zu vermeiden, umgangen wird, wenn Sie null für den Stamm übergeben.

Viele Entwickler nehmen dieses Verhalten zu bedeuten, dass die ordnungsgemäße Möglichkeit zum Deaktivieren der Anlage auf Inflation durch die Übergabe von Null als root; in vielen Fällen nicht einmal bewusst, dass die drei Parameter-Version von inflate() existiert.

More on Layout Inflation

+2

-1 diese Antwort kopiert einfach aus dem Artikel und erklärt damit, was (gute) Inflation ist. Das OP weiß das vermutlich und fragt nach einem Spezialfall, zu dem diese Antwort nichts hinzufügt – avalancha