Layoutansichten an Architekturkomponenten binden

Die AndroidX-Bibliothek enthält die Architekturkomponenten, mit denen Sie robuste, testbare und wartbare Anwendungen erstellen können. Die Datenbindungsbibliothek arbeitet nahtlos mit den Architekturkomponenten zusammen, um die Entwicklung Ihrer UI weiter zu vereinfachen. Die Layouts in Ihrer App können an die Daten in den Architekturkomponenten gebunden werden. Dadurch können Sie den Lebenszyklus des UI-Controllers verwalten und die UI über Datenänderungen informieren.

Auf dieser Seite wird gezeigt, wie Sie die Architekturkomponenten in Ihre Anwendung einbinden, um die Datenbindungsbibliothek optimal zu nutzen.

Mit LiveData die Benutzeroberfläche über Datenänderungen informieren

Sie können LiveData-Objekte als Datenbindungsquelle verwenden, um die UI automatisch über Änderungen an den Daten zu informieren. Weitere Informationen zu dieser Architekturkomponente finden Sie in der LiveData-Übersicht.

Im Gegensatz zu Objekten, die Observable implementieren (z. B. beobachtbare Felder), wissen LiveData-Objekte den Lebenszyklus der Beobachter, die die Datenänderungen abonniert haben. Dieses Wissen bietet viele Vorteile, die unter Vorteile von LiveData erläutert werden. Ab Android Studio Version 3.1 können Sie im Datenbindungscode beobachtbare Felder durch LiveData-Objekte ersetzen.

Wenn Sie ein LiveData-Objekt mit Ihrer Bindungsklasse verwenden möchten, müssen Sie einen Lebenszyklusinhaber angeben, um den Bereich des LiveData-Objekts zu definieren. Im folgenden Beispiel wird die Aktivität als Lebenszyklusinhaber angegeben, nachdem die Bindungsklasse instanziiert wurde:

Kotlin

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.setLifecycleOwner(this)
    }
}

Java

class ViewModelActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Inflate view and obtain an instance of the binding class.
        UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user);

        // Specify the current activity as the lifecycle owner.
        binding.setLifecycleOwner(this);
    }
}

Sie können eine ViewModel-Komponente verwenden, wie im folgenden Abschnitt erläutert, um die Daten an das Layout zu binden. In der ViewModel-Komponente können Sie das LiveData-Objekt verwenden, um die Daten zu transformieren oder mehrere Datenquellen zusammenzuführen. Das folgende Beispiel zeigt, wie die Daten im ViewModel transformiert werden:

Kotlin

class ScheduleViewModel : ViewModel() {
    val userName: LiveData

    init {
        val result = Repository.userName
        userName = Transformations.map(result) { result -> result.value }
    }
}

Java

class ScheduleViewModel extends ViewModel {
    LiveData username;

    public ScheduleViewModel() {
        String result = Repository.userName;
        userName = Transformations.map(result, result -> result.value);
    }
}

ViewModel zum Verwalten von UI-bezogenen Daten verwenden

Die Datenbindungsbibliothek funktioniert nahtlos mit ViewModel-Komponenten. Der ViewModel gibt die Daten frei, die vom Layout beobachtet werden, und reagiert auf seine Änderungen. Wenn Sie ViewModel-Komponenten mit der Datenbindungsbibliothek verwenden, können Sie die UI-Logik aus den Layouts in die Komponenten verschieben, die einfacher zu testen sind. Die Datenbindungsbibliothek stellt bei Bedarf sicher, dass die Ansichten an die Datenquelle gebunden bzw. von ihr getrennt werden. Die meiste Arbeit besteht darin, sicherzustellen, dass Sie die richtigen Daten bereitstellen. Weitere Informationen zu dieser Architekturkomponente finden Sie in der Übersicht zu ViewModel.

Wenn Sie die ViewModel-Komponente mit der Datenbindungsbibliothek verwenden möchten, müssen Sie Ihre Komponente instanziieren, die von der ViewModel-Klasse übernimmt, eine Instanz Ihrer Bindungsklasse abrufen und die ViewModel-Komponente einem Attribut in der Bindungsklasse zuweisen. Das folgende Beispiel zeigt, wie die Komponente mit der Bibliothek verwendet wird:

Kotlin

class ViewModelActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // Obtain the ViewModel component.
        val userModel: UserModel by viewModels()

        // Inflate view and obtain an instance of the binding class.
        val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)

        // Assign the component to a property in the binding class.
        binding.viewmodel = userModel
    }
}

Java

class ViewModelActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Obtain the ViewModel component.
        UserModel userModel = new ViewModelProvider(this).get(UserModel.class);

        // Inflate view and obtain an instance of the binding class.
        UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user);

        // Assign the component to a property in the binding class.
        binding.viewmodel = userModel;
    }
}

Weisen Sie in Ihrem Layout die Eigenschaften und Methoden der ViewModel-Komponente den entsprechenden Ansichten mithilfe von Bindungsausdrücken zu, wie im folgenden Beispiel gezeigt:

<CheckBox
    android:id="@+id/rememberMeCheckBox"
    android:checked="@{viewmodel.rememberMe}"
    android:onCheckedChanged="@{() -> viewmodel.rememberMeChanged()}" />

Verwenden Sie ein Observable ViewModel, um mehr Kontrolle über Bindungsadapter zu haben.

Mit einer ViewModel-Komponente, die die Observable-Schnittstelle implementiert, können Sie andere Anwendungskomponenten über Änderungen an den Daten informieren, ähnlich wie bei einem LiveData-Objekt.

In einigen Situationen empfiehlt es sich, anstelle von LiveData-Objekten eine ViewModel-Komponente zu verwenden, die die Observable-Schnittstelle implementiert, auch wenn Sie die Funktionen zur Lebenszyklusverwaltung von LiveData verlieren. Wenn Sie eine ViewModel-Komponente verwenden, die Observable implementiert, erhalten Sie mehr Kontrolle über die Bindungsadapter in Ihrer App. Mit diesem Muster haben Sie beispielsweise mehr Kontrolle über die Benachrichtigungen, wenn sich Daten ändern. Sie können damit auch eine benutzerdefinierte Methode angeben, um den Wert eines Attributs in der bidirektionalen Datenbindung festzulegen.

Wenn Sie eine beobachtbare ViewModel-Komponente implementieren möchten, müssen Sie eine Klasse erstellen, die die Werte der ViewModel-Klasse übernimmt und die Observable-Schnittstelle implementiert. Mit den Methoden addOnPropertyChangedCallback() und removeOnPropertyChangedCallback() können Sie eine benutzerdefinierte Logik bereitstellen, wenn ein Beobachter Benachrichtigungen abonniert oder abbestellt. Sie können auch eine benutzerdefinierte Logik angeben, die ausgeführt wird, wenn sich Attribute in der Methode notifyPropertyChanged() ändern. Das folgende Codebeispiel zeigt, wie ein beobachtbares ViewModel implementiert wird:

Kotlin

/**
 * A ViewModel that is also an Observable,
 * to be used with the Data Binding Library.
 */
open class ObservableViewModel : ViewModel(), Observable {
    private val callbacks: PropertyChangeRegistry = PropertyChangeRegistry()

    override fun addOnPropertyChangedCallback(
            callback: Observable.OnPropertyChangedCallback) {
        callbacks.add(callback)
    }

    override fun removeOnPropertyChangedCallback(
            callback: Observable.OnPropertyChangedCallback) {
        callbacks.remove(callback)
    }

    /**
     * Notifies observers that all properties of this instance have changed.
     */
    fun notifyChange() {
        callbacks.notifyCallbacks(this, 0, null)
    }

    /**
     * Notifies observers that a specific property has changed. The getter for the
     * property that changes must be marked with the @Bindable annotation to
     * generate a field in the BR class to be used as the fieldId parameter.
     *
     * @param fieldId The generated BR id for the Bindable field.
     */
    fun notifyPropertyChanged(fieldId: Int) {
        callbacks.notifyCallbacks(this, fieldId, null)
    }
}

Java

/**
 * A ViewModel that is also an Observable,
 * to be used with the Data Binding Library.
 */
class ObservableViewModel extends ViewModel implements Observable {
    private PropertyChangeRegistry callbacks = new PropertyChangeRegistry();

    @Override
    protected void addOnPropertyChangedCallback(
            Observable.OnPropertyChangedCallback callback) {
        callbacks.add(callback);
    }

    @Override
    protected void removeOnPropertyChangedCallback(
            Observable.OnPropertyChangedCallback callback) {
        callbacks.remove(callback);
    }

    /**
     * Notifies observers that all properties of this instance have changed.
     */
    void notifyChange() {
        callbacks.notifyCallbacks(this, 0, null);
    }

    /**
     * Notifies observers that a specific property has changed. The getter for the
     * property that changes must be marked with the @Bindable annotation to
     * generate a field in the BR class to be used as the fieldId parameter.
     *
     * @param fieldId The generated BR id for the Bindable field.
     */
    void notifyPropertyChanged(int fieldId) {
        callbacks.notifyCallbacks(this, fieldId, null);
    }
}

Weitere Informationen

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