Generierte Bindungsklassen

Die Datenbindungsbibliothek generiert Bindungsklassen, mit denen Sie auf die Variablen und Ansichten ändern. In dieser Dokumentation wird gezeigt, wie Sie die generierten Bindungsklassen anzupassen.

Die generierte Bindungsklasse verknüpft die Layoutvariablen mit den Ansichten in der Layout. Sie können den Namen und das Paket des Bindung. Alle generierten Bindungsklassen übernehmen die Klasse ViewDataBinding.

Für jede Layoutdatei wird eine Bindungsklasse generiert. Standardmäßig wird der Name des ist der Name der Layoutdatei, die mit der Binding in die Pascal-Groß-/Kleinschreibung konvertiert wird. Suffix hinzugefügt. Wenn der Layout-Dateiname beispielsweise activity_main.xml, die entsprechende generierte Klasse ist ActivityMainBinding. Diese Klasse enthält alle Bindungen, von den Layouteigenschaften bis hin zur und weiß, wie Werte für die Bindungsausdrücke zugewiesen werden.

Bindungsobjekt erstellen

Das Binding-Objekt wird sofort nach dem Aufblähen des Layouts erstellt, Ansichtshierarchie vor der Bindung an die Ansichten mit Ausdrücke innerhalb des Layouts. Die gängigste Methode zum Binden des Objekts an ein die statischen Methoden für die Bindungsklasse verwenden. Sie können die Hierarchie anzeigen und das Objekt an diese binden. Dazu verwenden Sie die Methode inflate() der binding-Klasse 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 inflate()-Methode, die ViewGroup-Objekt zusätzlich zum LayoutInflater-Objekt , wie Beispiel:

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 separat:

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 erstellen Sie die Bindung mithilfe des Klasse DataBindingUtil, Dies wird 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 einer Fragment, ListView oder RecyclerView können Sie den Adapter verwenden, inflate(). der Binding-Klassen oder der Klasse DataBindingUtil, wie 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);

Datenansichten mit IDs

Die Datenbindungsbibliothek erstellt ein unveränderliches Feld in der Bindungsklasse für die über eine ID im Layout verfügt. Beispiel: Die Datenbindungsbibliothek erstellt die Felder firstName und lastName vom Typ TextView aus der folgendes 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, aus der Ansichtshierarchie in einem Einzelkarte/-ticket. Dieser Mechanismus kann schneller sein als das Aufrufen der findViewById() für jede Ansicht im Layout.

IDs sind nicht so notwendig wie ohne Datenbindung, aber es gibt dennoch in denen Zugriff auf Ansichten über Code erforderlich ist.

Variablen

Die Data Binding Library generiert Zugriffsmethoden für jede deklarierte Variable im Layout. 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>

AnsichtsStubs

Im Gegensatz zu normalen Ansichten können ViewStub-Objekte als unsichtbare Ansichten. Wenn sie sichtbar oder explizit aufgebläht sind, ersetzen sie sich im Layout, indem sie ein anderes Layout aufblähen.

Da ViewStub aus der Ansichtshierarchie verschwindet, wird die Ansicht in der Ansicht Bindungsobjekt muss ebenfalls ausgeblendet werden, damit es von der automatischen Speicherbereinigung beansprucht werden kann. Da die Aufrufe endgültig sind, Objekt ViewStubProxy ersetzt die ViewStub in der generierten Bindungsklasse, sodass Sie Zugriff auf ViewStub (sofern vorhanden) und auf die aufgeblähte Ansicht Hierarchie, wenn ViewStub zu hoch ist.

Beim Aufblähen eines anderen Layouts muss eine Bindung für das neue Layout erstellt werden. Daher muss ViewStubProxy auf ViewStub warten OnInflateListener und die Bindung bei Bedarf einrichten. Da pro Listener nur ein Listener vorhanden sein kann, können Sie mit ViewStubProxy ein OnInflateListener festlegen, das nachdem die Bindung hergestellt wurde.

Sofort binden

Wenn sich eine Variable oder ein beobachtbares Objekt ändert, wird die Bindung planmäßig geändert vor dem nächsten Frame. Manchmal muss eine Bindung jedoch ausgeführt werden. sofort. Um die Ausführung zu erzwingen, verwenden Sie den executePendingBindings() .

Dynamische Variablen

Manchmal ist die spezifische Bindungsklasse unbekannt. Beispiel: RecyclerView.Adapter Wenn Sie für beliebige Layouts arbeiten, kennen Sie die spezifische Bindungsklasse nicht. Es muss den Bindungswert während des Aufrufs der onBindViewHolder() .

Im folgenden Beispiel haben alle Layouts, die vom RecyclerView an ein item. Das BindingHolder-Objekt hat eine getBinding()-Methode der Rückgabe der ViewDataBinding-Basis .

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 kein . Durch die Datenbindung wird jede Variable oder jedes Feld während der Auswertung lokalisiert, um Gleichzeitigkeitsprobleme vermeiden.

Namen von benutzerdefinierten Bindungsklassen

Standardmäßig wird basierend auf dem Namen der Layoutdatei eine Bindungsklasse generiert. beginnend mit einem Großbuchstaben, wobei Unterstriche ( _) entfernt und der auf den Buchstaben und nach dem Wort Binding. Zum Beispiel könnte die Layoutdatei contact_item.xml generiert die Klasse ContactItemBinding. Der Kurs wurde platziert in einem databinding-Paket unter dem Modulpaket. Wenn das Modul zum Beispiel Paket com.example.my.app lautet, wird die Binding-Klasse im com.example.my.app.databinding-Paket.

Bindungsklassen können umbenannt oder in verschiedenen Paketen platziert werden, indem die Attribut class des Elements data. Das folgende Layout generiert die Bindungsklasse ContactItem im Paket databinding im aktuelles Modul:

<data class="ContactItem">
    ...
</data>

Sie können die Bindungsklasse in einem anderen Paket generieren, indem Sie der Klasse ein Präfix voranstellen mit einem Punkt. Im folgenden Beispiel wird die Bindungsklasse in der Module:

<data class=".ContactItem">
    ...
</data>

Sie können auch den vollständigen Paketnamen dort angeben, wo sich die Bindungsklasse befinden soll. generiert. Im folgenden Beispiel wird die Bindungsklasse ContactItem in der com.example-Paket:

<data class="com.example.ContactItem">
    ...
</data>

Weitere Informationen

Weitere Informationen zur Datenbindung finden Sie in den folgenden zusätzlichen Ressourcen.