Die Datenbindungsbibliothek generiert Bindungsklassen, mit denen Sie auf die Variablen und Ansichten des Layouts zugreifen können. In dieser Dokumentation erfahren Sie, wie Sie generierte Bindungsklassen erstellen und anpassen.
Die generierte Bindungsklasse verknüpft die Layoutvariablen mit den Ansichten innerhalb des Layouts. Sie können den Namen und das Paket der Bindung anpassen. Alle generierten Bindungsklassen werden von der Klasse ViewDataBinding
übernommen.
Für jede Layoutdatei wird eine Bindungsklasse generiert. Der Name der Klasse ist standardmäßig der Name der Layoutdatei, die in die Pascal-Groß- und Kleinschreibung konvertiert wird, wobei das Suffix Binding hinzugefügt wird. Lautet der Name der Layoutdatei beispielsweise activity_main.xml
, ist die entsprechende generierte Klasse ActivityMainBinding
.
Diese Klasse enthält alle Bindungen von den Layouteigenschaften zu den Ansichten des Layouts und weiß, wie Werte für die Bindungsausdrücke zugewiesen werden.
Bindungsobjekt erstellen
Das Bindungsobjekt wird unmittelbar nach der Layout-Inflation erstellt, damit die Ansichtshierarchie nicht geändert wird, bevor es an die Ansichten mit Ausdrücken im Layout gebunden wird. Die gängigste Methode zum Binden des Objekts an ein Layout sind statische Methoden für die Bindungsklasse. Sie können die Ansichtshierarchie erweitern und das Objekt an diese binden. Dazu verwenden Sie die Methode inflate()
der Bindungsklasse, wie im folgenden Beispiel gezeigt:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding: MyLayoutBinding = MyLayoutBinding.inflate(layoutInflater) setContentView(binding.root) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.root); }
Es gibt eine alternative Version der Methode inflate()
, die zusätzlich zum Objekt LayoutInflater
ein ViewGroup
-Objekt verwendet, wie im folgenden Beispiel gezeigt:
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)
Java
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);
Wenn das Layout mit einem anderen Mechanismus aufgebläht wird, können Sie es wie folgt separat binden:
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)
Java
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
Manchmal kennen Sie den Bindungstyp nicht im Voraus. In solchen Fällen können Sie die Bindung mit der Klasse DataBindingUtil
erstellen, wie im folgenden Code-Snippet gezeigt:
Kotlin
val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent) val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)
Java
View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent); ViewDataBinding binding = DataBindingUtil.bind(viewRoot);
Wenn Sie Datenbindungselemente in einem Fragment
-, ListView
- oder RecyclerView
-Adapter verwenden, sollten Sie die inflate()
-Methoden der Bindungsklassen oder die DataBindingUtil
-Klasse verwenden, wie im folgenden Codebeispiel gezeigt:
Kotlin
val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false) // or val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)
Java
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false); // or ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
Ansichten mit IDs
Die Datenbindungsbibliothek erstellt für jede Ansicht, die eine ID im Layout hat, in der Bindungsklasse ein unveränderliches Feld. Die Datenbindungsbibliothek erstellt beispielsweise die Felder firstName
und lastName
vom Typ TextView
mit dem folgenden Layout:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"
android:id="@+id/firstName"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"
android:id="@+id/lastName"/>
</LinearLayout>
</layout>
Die Bibliothek extrahiert die Ansichten, einschließlich der IDs, in einem einzigen Durchlauf aus der Ansichtshierarchie. Dieser Mechanismus ist möglicherweise schneller als der Aufruf der Methode findViewById()
für jede Ansicht im Layout.
IDs sind nicht so notwendig wie ohne Datenbindung. Es gibt jedoch immer noch Fälle, in denen ein Zugriff auf Ansichten aus Code erforderlich ist.
Variablen
Die Datenbindungsbibliothek generiert Zugriffsmethoden für jede im Layout deklarierte Variable. Das folgende Layout generiert beispielsweise Setter- und Getter-Methoden in der Bindungsklasse für die Variablen user
, image
und note
:
<data>
<import type="android.graphics.drawable.Drawable"/>
<variable name="user" type="com.example.User"/>
<variable name="image" type="Drawable"/>
<variable name="note" type="String"/>
</data>
ViewStubs
Im Gegensatz zu normalen Ansichten beginnen ViewStub
-Objekte als unsichtbare Ansichten. Wenn sie sichtbar oder explizit aufgebläht werden, ersetzen sie sich im Layout durch ein anderes Layout.
Da ViewStub
aus der Ansichtshierarchie verschwindet, muss auch die Ansicht im Binding-Objekt ausgeblendet werden, damit sie durch die automatische Speicherbereinigung beansprucht werden kann.
Da die Ansichten endgültig sind, ersetzt ein ViewStubProxy
-Objekt den ViewStub
in der generierten Bindungsklasse. Dadurch erhalten Sie Zugriff auf die ViewStub
, sofern vorhanden, und auf die aufgeblähte Ansichtshierarchie, wenn ViewStub
aufgebläht ist.
Wird ein anderes Layout künstlich erzeugt, muss eine Bindung für das neue Layout festgelegt werden.
Daher muss der ViewStubProxy
auf ViewStub
OnInflateListener
warten und bei Bedarf die Bindung erstellen. Da immer nur ein Listener vorhanden sein kann, können Sie mit ViewStubProxy
ein OnInflateListener
festlegen, das nach dem Einrichten der Bindung aufgerufen wird.
Sofortige Bindung
Wenn sich eine Variable oder ein beobachtbares Objekt ändert, wird die Bindung vor dem nächsten Frame geplant. Manchmal muss die Bindung jedoch sofort ausgeführt werden. Verwenden Sie die Methode executePendingBindings()
, um die Ausführung zu erzwingen.
Dynamische Variablen
Manchmal ist die spezifische Bindungsklasse unbekannt. Beispielsweise kennt ein RecyclerView.Adapter
, das für beliebige Layouts ausgeführt wird, die spezifische Bindungsklasse nicht. Der Bindungswert muss während des Aufrufs der Methode onBindViewHolder()
zugewiesen werden.
Im folgenden Beispiel haben alle Layouts, an die RecyclerView
gebunden wird, eine item
-Variable. Das BindingHolder
-Objekt hat eine getBinding()
-Methode, die die ViewDataBinding
-Basisklasse zurückgibt.
Kotlin
override fun onBindViewHolder(holder: BindingHolder, position: Int) { item: T = items.get(position) holder.binding.setVariable(BR.item, item); holder.binding.executePendingBindings(); }
Java
public void onBindViewHolder(BindingHolder holder, int position) { final T item = items.get(position); holder.getBinding().setVariable(BR.item, item); holder.getBinding().executePendingBindings(); }
Hintergrundthread
Sie können Ihr Datenmodell in einem Hintergrundthread ändern, solange es sich nicht um eine Sammlung handelt. Die Datenbindung lokalisiert jede Variable oder jedes Feld während der Bewertung, um Probleme mit der Gleichzeitigkeit zu vermeiden.
Namen von benutzerdefinierten Bindungsklassen
Standardmäßig wird eine Bindungsklasse anhand des Namens der Layoutdatei generiert. Sie beginnt mit einem Großbuchstaben, entfernt die Unterstriche ( _), die Großschreibung des folgenden Buchstabens und das Wort Binding wird als Suffix hinzugefügt. Die Layoutdatei contact_item.xml
generiert beispielsweise die Klasse ContactItemBinding
. Die Klasse wird in einem databinding
-Paket unter dem Modulpaket platziert. Wenn das Modulpaket beispielsweise com.example.my.app
ist, wird die Bindungsklasse im Paket com.example.my.app.databinding
platziert.
Bindungsklassen können durch Anpassung des Attributs class
des Elements data
umbenannt oder in verschiedenen Paketen platziert werden. Das folgende Layout generiert beispielsweise die Bindungsklasse ContactItem
im Paket databinding
im aktuellen Modul:
<data class="ContactItem">
...
</data>
Sie können die Bindungsklasse in einem anderen Paket generieren, indem Sie dem Klassennamen einen Punkt voranstellen. Im folgenden Beispiel wird die Bindungsklasse im Modulpaket generiert:
<data class=".ContactItem">
...
</data>
Sie können auch den vollständigen Paketnamen verwenden, für den die Bindungsklasse generiert werden soll. Im folgenden Beispiel wird die Bindungsklasse ContactItem
im Paket com.example
erstellt:
<data class="com.example.ContactItem">
...
</data>
Weitere Informationen
Weitere Informationen zur Datenbindung finden Sie in den folgenden zusätzlichen Ressourcen.
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Layouts und Bindungsausdrücke
- Datenbindungsbibliothek
- Bindung ansehen