Mit beobachtbaren Datenobjekten arbeiten

Beobachtbarkeit bezieht sich auf die Fähigkeit eines Objekts, andere über Änderungen in seinen Daten. Mit der Datenbindungsbibliothek können Sie Objekte, Felder oder zu beobachten.

Sie können ein beliebiges Objekt für die Datenbindung verwenden, das Ändern des Objekts führt jedoch nicht dazu, wird die Benutzeroberfläche automatisch aktualisiert. Mit Datenbindung können Sie Ihre Daten Objekte, die andere Objekte – sogenannte Listener – benachrichtigen können, wenn ihre Daten ändern. Es gibt drei Arten von beobachtbaren Klassen: fields, collections und Objekte.

Wenn eines dieser beobachtbaren Datenobjekte an die Benutzeroberfläche gebunden ist und die Eigenschaft ändert sich die Benutzeroberfläche automatisch.

Beobachtbare Felder

Wenn Ihre Klassen nur wenige Attribute haben, lohnt es sich möglicherweise nicht, Klassen erstellen, die die Observable-Schnittstelle. In dieser können Sie die generische Observable-Klasse und Folgendes verwenden: primitiven Klassen verwenden, um Felder beobachtbar zu machen:

Beobachtbare Felder sind eigenständige, beobachtbare Objekte, ein. Die einfachen Versionen vermeiden Boxen und Unboxing während des Zugriffs Geschäftsabläufe. Um diesen Mechanismus zu verwenden, erstellen Sie ein public final-Attribut in der Java- Programmiersprache oder eine schreibgeschützte Eigenschaft in Kotlin, wie in den folgendes Beispiel:

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();
}

Um auf den Feldwert zuzugreifen, verwenden Sie die Methode set() und Zugriffsmethoden für get() oder Kotlin-Property verwenden Syntax:

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 Zugriff auf diese Strukturen mithilfe eines Schlüssels. Die ObservableArrayMap Kurs ist nützlich, wenn der Schlüssel ein Referenztyp ist, wie z. B. String, wie in der folgendes Beispiel:

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 können Sie die Karte mithilfe der Zeichenfolgenschlüssel finden, wie in den folgendes Beispiel:

<data>
    <import type="android.databinding.ObservableMap"/>
    <variable name="user" type="ObservableMap&lt;String, Object&gt;"/>
</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 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 über die Indexe auf die Liste zugreifen, wie in den folgendes Beispiel:

<data>
    <import type="android.databinding.ObservableList"/>
    <import type="com.example.my.app.Fields"/>
    <variable name="user" type="ObservableList&lt;Object&gt;"/>
</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 Listener, die über Property-Änderungen der beobachtbaren -Objekt enthält.

Die Observable-Oberfläche bietet einen Mechanismus zum Hinzufügen und Entfernen von Listenern. Sie können jedoch festlegen, wann Benachrichtigungen gesendet werden. Um die Entwicklung zu erleichtern, Die Bindungsbibliothek enthält die BaseObservable-Klasse, die Implementiert den Listener-Registrierungsmechanismus. Die Datenklasse, die BaseObservable ist dafür verantwortlich, bei Änderungen der Unterkünfte benachrichtigt zu werden. Aufgabe Weisen Sie dementsprechend eine Bindable-Anmerkung zu an den Getter an und rufen Sie notifyPropertyChanged() im Setter, 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);
    }
}

Durch die Datenbindung wird im Modulpaket eine Klasse mit dem Namen BR generiert, die Folgendes enthält: Die IDs der für die Datenbindung verwendeten Ressourcen. Die Anmerkung Bindable generiert während der Kompilierung einen Eintrag in der BR-Klassendatei. Wenn die Basisklasse für Datenklassen kann nicht geändert werden, sondern Sie können die Observable-Schnittstelle implementieren. mit einer PropertyChangeRegistry , um Hörer effizient zu registrieren und zu benachrichtigen.

Lebenszyklusbewusste Objekte

Die Layouts in Ihrer App können auch an Datenbindungsquellen gebunden werden, die automatisch die UI über Änderungen an den Daten zu informieren. So werden Ihre Bindungen und werden nur ausgelöst, wenn die Benutzeroberfläche auf dem Bildschirm sichtbar ist.

Datenbindung unterstützt StateFlow und LiveData Weitere Informationen zu Verwendung von LiveData in der Datenbindung, siehe LiveData verwenden, um die UI über Daten zu informieren .

StateFlow verwenden

Wenn Ihre App Kotlin mit coroutines verwendet, können Sie StateFlow-Objekte als Datenbindungsquelle. So verwenden Sie ein StateFlow-Objekt mit Bindungsklasse haben, geben Sie einen Lebenszyklusinhaber an, um den Bereich der StateFlow-Objekt. Im folgenden Beispiel wird die Aktivität als Lebenszyklusinhaber nach der Instanziierung der Bindungsklasse:

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 die Architektur binden beschrieben Komponenten, Datenbindung ist nahtlos mit ViewModel kompatibel Objekte. 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 zu die entsprechenden Ansichten mithilfe von Bindungsausdrücken erstellen, wie im Folgenden gezeigt: Beispiel:

<TextView
    android:id="@+id/name"
    android:text="@{viewmodel.username}" />

Die Benutzeroberfläche wird automatisch aktualisiert, wenn sich der Wert des Nutzernamens ändert.

StateFlow-Unterstützung deaktivieren

Für Apps mit Kotlin und AndroidX wird automatisch StateFlow unterstützt. Datenbindung bereits enthalten. Das bedeutet, dass die Koroutinen-Abhängigkeit automatisch in Ihre App eingebunden, falls die Abhängigkeit nicht bereits verfügbar ist.

Sie können diese Funktion deaktivieren, indem Sie Folgendes in Ihre build.gradle-Datei:

Cool

android {
    ...
    dataBinding {
        addKtx = false
    }
}

Kotlin

android {
    ...
    dataBinding {
        addKtx = false
    }
}

Alternativ können Sie StateFlow in Ihrem Projekt global deaktivieren, indem Sie folgende Zeile in die Datei gradle.properties ein:

Cool

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