Beobachtbarkeit bezieht sich auf die Fähigkeit eines Objekts, andere über Änderungen an seinen Daten zu informieren. Mit der Data Binding Library können Sie Objekte, Felder oder Sammlungen beobachtbar machen.
Sie können ein beliebiges Objekt für die Datenbindung verwenden. Durch das Ändern des Objekts wird jedoch nicht automatisch die UI aktualisiert. Mithilfe der Datenbindung können Sie Ihren Datenobjekten die Möglichkeit geben, andere Objekte (sogenannte Listener) zu benachrichtigen, wenn sich ihre Daten ändern. Es gibt drei Arten von beobachtbaren Klassen: Felder, Sammlungen und Objekte.
Wenn eines dieser beobachtbaren Datenobjekte an die UI gebunden ist und sich eine Eigenschaft des Datenobjekts ändert, wird die UI automatisch aktualisiert.
Beobachtbare Felder
Wenn Ihre Klassen nur wenige Attribute haben, lohnt es sich möglicherweise nicht, Klassen zu erstellen, die die Schnittstelle Observable
implementieren. In diesem Fall können Sie die generische Observable
-Klasse und die folgenden primitiven Klassen verwenden, um Felder beobachtbar zu machen:
ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable
Beobachtbare Felder sind eigenständige beobachtbare Objekte mit einem einzelnen Feld. Die primitiven Versionen vermeiden Boxen und Unboxing während Zugriffvorgängen. Um diesen Mechanismus zu verwenden, erstellen Sie ein public final
-Attribut in der Programmiersprache Java oder ein schreibgeschütztes Attribut in Kotlin, wie im folgenden Beispiel gezeigt:
Kotlin
class User { val firstName = ObservableField<String>() val lastName = ObservableField<String>() val age = ObservableInt() }
Java
private static class User { public final ObservableField<String> firstName = new ObservableField<>(); public final ObservableField<String> lastName = new ObservableField<>(); public final ObservableInt age = new ObservableInt(); }
Verwenden Sie die Zugriffsmethoden set()
und get()
oder die Kotlin-Attributsyntax, um auf den Feldwert zuzugreifen:
Kotlin
user.firstName = "Google" val age = user.age
Java
user.firstName.set("Google"); int age = user.age.get();
Beobachtbare Sammlungen
Einige Apps verwenden dynamische Strukturen zur Speicherung von Daten. Beobachtbare Sammlungen ermöglichen den Zugriff
auf diese Strukturen mithilfe eines Schlüssels. Die Klasse ObservableArrayMap
ist nützlich, wenn der Schlüssel ein Referenztyp wie String
ist, wie im folgenden Beispiel gezeigt:
Kotlin
ObservableArrayMap<String, Any>().apply { put("firstName", "Google") put("lastName", "Inc.") put("age", 17) }
Java
ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); user.put("firstName", "Google"); user.put("lastName", "Inc."); user.put("age", 17);
Im Layout finden Sie die Karte mithilfe der Stringschlüssel, wie im folgenden Beispiel gezeigt:
<data>
<import type="android.databinding.ObservableMap"/>
<variable name="user" type="ObservableMap<String, Object>"/>
</data>
…
<TextView
android:text="@{user.lastName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text="@{String.valueOf(1 + (Integer)user.age)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Die Klasse ObservableArrayList
ist nützlich, wenn der Schlüssel eine Ganzzahl ist:
Kotlin
ObservableArrayList<Any>().apply { add("Google") add("Inc.") add(17) }
Java
ObservableArrayList<Object> user = new ObservableArrayList<>(); user.add("Google"); user.add("Inc."); user.add(17);
Im Layout können Sie wie im folgenden Beispiel über die Indexe auf die Liste zugreifen:
<data>
<import type="android.databinding.ObservableList"/>
<import type="com.example.my.app.Fields"/>
<variable name="user" type="ObservableList<Object>"/>
</data>
…
<TextView
android:text='@{user[Fields.LAST_NAME]}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Beobachtbare Objekte
Eine Klasse, die die Observable
-Schnittstelle implementiert, ermöglicht die Registrierung von Listenern, die über Attributänderungen des beobachtbaren Objekts benachrichtigt werden möchten.
Die Schnittstelle Observable
verfügt über einen Mechanismus zum Hinzufügen und Entfernen von Listenern. Sie entscheiden jedoch, wann Benachrichtigungen gesendet werden. Zur Vereinfachung der Entwicklung stellt die Datenbindungsbibliothek die Klasse BaseObservable
bereit, die den Listener-Registrierungsmechanismus implementiert. Die Datenklasse, in der BaseObservable
implementiert ist, sendet Benachrichtigungen, wenn sich die Attribute ändern. Weisen Sie dazu dem Getter eine Bindable
-Annotation zu und rufen Sie die Methode notifyPropertyChanged()
im Setter auf, wie im folgenden Beispiel gezeigt:
Kotlin
class User : BaseObservable() { @get:Bindable var firstName: String = "" set(value) { field = value notifyPropertyChanged(BR.firstName) } @get:Bindable var lastName: String = "" set(value) { field = value notifyPropertyChanged(BR.lastName) } }
Java
private static class User extends BaseObservable { private String firstName; private String lastName; @Bindable public String getFirstName() { return this.firstName; } @Bindable public String getLastName() { return this.lastName; } public void setFirstName(String firstName) { this.firstName = firstName; notifyPropertyChanged(BR.firstName); } public void setLastName(String lastName) { this.lastName = lastName; notifyPropertyChanged(BR.lastName); } }
Die Datenbindung generiert im Modulpaket eine Klasse mit dem Namen BR
, die die IDs der für die Datenbindung verwendeten Ressourcen enthält. Die Annotation Bindable
generiert während der Kompilierung einen Eintrag in der Klassendatei BR
. Wenn die Basisklasse für Datenklassen nicht geändert werden kann, können Sie die Observable
-Schnittstelle mithilfe eines PropertyChangeRegistry
-Objekts implementieren, um Listener effizient zu registrieren und zu benachrichtigen.
Lebenszyklusbewusste Objekte
Die Layouts in Ihrer App können auch an Datenbindungsquellen gebunden werden, die die UI automatisch über Änderungen der Daten informieren. Auf diese Weise werden Ihre Bindungen Lebenszyklus berücksichtigen und nur ausgelöst, wenn die UI auf dem Bildschirm sichtbar ist.
Die Datenbindung unterstützt StateFlow
und LiveData
. Weitere Informationen zur Verwendung von LiveData
in der Datenbindung finden Sie unter Mit LiveData die UI über Datenänderungen informieren.
StateFlow verwenden
Wenn in Ihrer App Kotlin mit Koroutinen verwendet wird, können Sie StateFlow
-Objekte als Quelle für die Datenbindung verwenden. Wenn Sie ein StateFlow
-Objekt mit Ihrer Bindungsklasse verwenden möchten, geben Sie einen Lebenszyklusinhaber an, um den Bereich des StateFlow
-Objekts zu definieren. Im folgenden Beispiel wird die Aktivität als Lebenszyklusinhaber angegeben, nachdem die Bindungsklasse instanziiert wurde:
class ViewModelActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Inflate view and obtain an instance of the binding class.
val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)
// Specify the current activity as the lifecycle owner.
binding.lifecycleOwner = this
}
}
Wie unter Layoutansichten an Architekturkomponenten binden beschrieben, funktioniert die Datenbindung nahtlos mit ViewModel
-Objekten. So können Sie StateFlow
und ViewModel
zusammen verwenden:
class ScheduleViewModel : ViewModel() {
private val _username = MutableStateFlow<String>("")
val username: StateFlow<String> = _username
init {
viewModelScope.launch {
_username.value = Repository.loadUserName()
}
}
}
Weisen Sie in Ihrem Layout die Eigenschaften und Methoden des ViewModel
-Objekts den entsprechenden Ansichten mithilfe von Bindungsausdrücken zu, wie im folgenden Beispiel gezeigt:
<TextView
android:id="@+id/name"
android:text="@{viewmodel.username}" />
Die Benutzeroberfläche wird automatisch aktualisiert, wenn sich der Name-Wert des Nutzers ändert.
StateFlow-Unterstützung deaktivieren
Für Apps, die Kotlin und AndroidX verwenden, ist die StateFlow
-Unterstützung automatisch in der Datenbindung enthalten. Das bedeutet, dass die Koroutinenabhängigkeit automatisch in Ihre Anwendung aufgenommen wird, wenn sie nicht bereits verfügbar ist.
Sie können diese Funktion deaktivieren, indem Sie der Datei build.gradle
Folgendes hinzufügen:
Groovig
android { ... dataBinding { addKtx = false } }
Kotlin
android { ... dataBinding { addKtx = false } }
Alternativ können Sie StateFlow
global in Ihrem Projekt deaktivieren, indem Sie die folgende Zeile in die Datei gradle.properties
einfügen:
Groovig
android.defaults.databinding.addKtx = false
Kotlin
android.defaults.databinding.addKtx = false
Weitere Informationen
Weitere Informationen zur Datenbindung finden Sie in den folgenden Ressourcen:
Produktproben
Codelabs
Blogposts
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Modul „Gespeicherter Status“ für ViewModel
- Layoutansichten an Architekturkomponenten binden
- Paging-Bibliothek – Übersicht