Was ist der Nutzen von LayoutInflater
in Android?
Antworten
Zu viele Anzeigen?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.
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 neueView
(oLayout
) 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 SiesetContentView
enonCreate
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.
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.
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 dieseRecyclerView
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.
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 .
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);
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
- See previous answers
- Weitere Antworten anzeigen