385 Stimmen

Was macht der LayoutInflater in Android?

Was ist der Nutzen von LayoutInflater in Android?

337voto

Pentium10 Punkte 198024

En LayoutInflater Klasse wird verwendet, um den Inhalt von Layout-XML-Dateien in die entsprechenden View-Objekte zu instanziieren.

Mit anderen Worten: Es nimmt eine XML-Datei als Eingabe und erstellt daraus die View-Objekte.

259voto

Suragch Punkte 420096

Was bedeutet LayoutInflator tun?

Als ich mit der Android-Programmierung begann, war ich sehr verwirrt von LayoutInflater y findViewById . Manchmal haben wir das eine und manchmal das andere benutzt.

  • LayoutInflater wird verwendet, um eine neue View (o Layout ) Objekt aus einem Ihrer xml-Layouts.
  • findViewById gibt Ihnen nur einen Verweis auf eine Ansicht, die bereits erstellt wurde. Sie könnten denken, dass Sie noch keine Ansichten erstellt haben, aber immer wenn Sie setContentView en onCreate wird das Layout der Aktivität zusammen mit den Unteransichten im Hintergrund aufgeblasen (erstellt).

Wenn die Ansicht also bereits existiert, dann verwenden Sie findViewById . Wenn nicht, dann erstellen Sie es mit einer LayoutInflater .

Ejemplo

Hier ist ein Miniprojekt von mir, das beides zeigt LayoutInflater y findViewById in Aktion. Ohne besonderen Code sieht das Layout wie folgt aus.

enter image description here

Das blaue Quadrat ist ein benutzerdefiniertes Layout, das in das Hauptlayout mit include (siehe aquí für mehr). Sie wurde automatisch aufgeblasen, weil sie Teil der Inhaltsansicht ist. Wie Sie sehen können, ist der Code nichts Besonderes.

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Lassen Sie uns nun eine weitere Kopie unseres benutzerdefinierten Layouts aufblasen (erstellen) und einfügen.

enter image description here

LayoutInflater inflater = getLayoutInflater();
View myLayout = inflater.inflate(R.layout.my_layout, mainLayout, false);

Um das neue Ansichtslayout aufzublasen, musste ich dem Inflater nur den Namen meiner Xml-Datei mitteilen ( my_layout ), das übergeordnete Layout, dem ich es hinzufügen möchte ( mainLayout ), und dass ich es eigentlich noch nicht hinzufügen möchte ( false ). (Ich könnte auch das Elternteil auf null aber dann würden die Layout-Parameter der Root-Ansicht meines benutzerdefinierten Layouts ignoriert werden).

Hier ist es wieder im Kontext.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // inflate the main layout for the activity
        setContentView(R.layout.activity_main);

        // get a reference to the already created main layout
        LinearLayout mainLayout = (LinearLayout) findViewById(R.id.activity_main_layout);

        // inflate (create) another copy of our custom layout
        LayoutInflater inflater = getLayoutInflater();
        View myLayout = inflater.inflate(R.layout.my_layout, mainLayout, false);

        // make changes to our custom layout and its subviews
        myLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.colorAccent));
        TextView textView = (TextView) myLayout.findViewById(R.id.textView);
        textView.setText("New Layout");

        // add our custom layout to the main layout
        mainLayout.addView(myLayout);
    }
}

Beachten Sie, wie findViewById wird erst verwendet, nachdem ein Layout bereits aufgeblasen wurde.

Zusätzlicher Code

Hier ist die xml-Datei für das obige Beispiel.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main_layout"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <!-- Here is the inserted layout -->
    <include layout="@layout/my_layout"/>

</LinearLayout>

mein_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@color/colorPrimary">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:padding="5dp"
        android:textColor="@android:color/white"
        android:text="My Layout"/>

</RelativeLayout>

Wann brauchen Sie LayoutInflater

  • Am häufigsten verwenden die meisten Menschen es in einem RecyclerView . (Siehe diese RecyclerView Beispiele für eine Liste oder eine Gitter .) Sie müssen für jedes einzelne sichtbare Element in der Liste oder im Gitter ein neues Layout erstellen.
  • Sie können auch einen Layout Inflater verwenden, wenn Sie ein komplexes Layout haben, das Sie programmatisch hinzufügen möchten (wie in unserem Beispiel). Sie könnten das alles im Code machen, aber es ist viel einfacher, es zuerst in Xml zu definieren und es dann einfach aufzublasen.

165voto

Macarse Punkte 89366

Wenn Sie eine benutzerdefinierte Ansicht in einer ListView müssen Sie das Zeilenlayout definieren. Sie erstellen eine xml, in der Sie Android Widgets platzieren und dann im Code des Adapters müssen Sie etwas wie folgt tun:

public MyAdapter(Context context, List<MyObject> objects) extends ArrayAdapter {
  super(context, 1, objects);
  /* We get the inflator in the constructor */
  mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
  View view;
  /* We inflate the xml which gives us a view */
  view = mInflater.inflate(R.layout.my_list_custom_row, parent, false);

  /* Get the item in the adapter */
  MyObject myObject = getItem(position);

  /* Get the widget with id name which is defined in the xml of the row */
  TextView name = (TextView) view.findViewById(R.id.name);

  /* Populate the row's xml with info from the item */
  name.setText(myObject.getName());

  /* Return the generated view */
  return view;
}

Lesen Sie mehr in der offizielle Dokumentation .

33voto

Scott Hellam Punkte 439

LayoutInflater.inflate() bietet eine Möglichkeit, eine res/layout/*.xml-Datei, die eine Ansicht definiert, in ein tatsächliches View-Objekt zu konvertieren, das im Quellcode Ihrer Anwendung verwendet werden kann.

zwei grundlegende Schritte: den Inflater holen und dann die Ressource aufblasen

Wie kommt man an den Inflator?

LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

Wie erhalten Sie die Ansicht unter der Annahme, dass die Xml-Datei "list_item.xml" lautet?

View view = inflater.inflate(R.layout.list_item, parent, false);

22voto

MSquare Punkte 6151

Hier ist ein weiteres Beispiel, das dem vorherigen ähnelt, aber erweitert wurde, um die Aufblähparameter und das dynamische Verhalten, das sie bieten können, weiter zu demonstrieren.

Angenommen, Ihr ListView-Zeilenlayout kann eine variable Anzahl von TextViews haben. Dann blasen Sie zuerst die Basis-Element-Ansicht auf (genau wie im vorherigen Beispiel) und fügen dann in einer Schleife dynamisch TextViews zur Laufzeit hinzu. Durch die Verwendung von Android:layout_weight wird zusätzlich alles perfekt ausgerichtet.

Hier sind die Ressourcen für Layouts:

list_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" >
    <TextView 
        android:id="@+id/field1"
        android:layout_width="0dp"  
        android:layout_height="wrap_content" 
        android:layout_weight="2"/>
    <TextView 
        android:id="@+id/field2"
        android:layout_width="0dp"  
        android:layout_height="wrap_content" 
        android:layout_weight="1"
/>
</LinearLayout>

zeitplan_layout.xml

<?xml version="1.0" encoding="utf-8"?>
   <TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dp"  
    android:layout_height="wrap_content" 
    android:layout_weight="1"/>

Überschreiben Sie getView Methode in der Erweiterung der BaseAdapter-Klasse

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = activity.getLayoutInflater();
    View lst_item_view = inflater.inflate(R.layout.list_layout, null);
    TextView t1 = (TextView) lst_item_view.findViewById(R.id.field1);
    TextView t2 = (TextView) lst_item_view.findViewById(R.id.field2);
    t1.setText("some value");
    t2.setText("another value");

    // dinamically add TextViews for each item in ArrayList list_schedule
    for(int i = 0; i < list_schedule.size(); i++){
        View schedule_view = inflater.inflate(R.layout.schedule_layout, (ViewGroup) lst_item_view, false);
        ((TextView)schedule_view).setText(list_schedule.get(i));
        ((ViewGroup) lst_item_view).addView(schedule_view);
    }
    return lst_item_view;
}

Nota verschiedene Aufrufe der Inflate-Methode:

inflater.inflate(R.layout.list_layout, null); // no parent
inflater.inflate(R.layout.schedule_layout, (ViewGroup) lst_item_view, false); // with parent preserving LayoutParams

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X