Praca z obserwowalnymi obiektami danych

Dostrzegalność odnosi się do zdolności obiektu, aby powiadamiać innych o zmian w danych. Biblioteka wiązań danych umożliwia tworzenie obiektów, pól które można zaobserwować.

Do powiązania danych możesz użyć dowolnego obiektu, ale modyfikacja obiektu nie powoduje automatyczne zaktualizowanie interfejsu użytkownika. Aby przekazać dane, możesz użyć wiązania danych uniemożliwia powiadamianie innych obiektów (nazywanych detektorami), gdy zmiany danych. Istnieją 3 typy możliwych do obserwowania klas: fields, collections i obiektów.

Gdy jeden z tych obserwowalnych obiektów danych jest powiązany z interfejsem użytkownika i usługą gdy zmodyfikujesz obiekt danych, interfejs aktualizuje się automatycznie.

Obserwowalne pola

Jeśli Twoje zajęcia mają tylko kilka właściwości, być może nie warto tworzyć klasy, które stosują Observable. W tym możesz użyć ogólnej klasy Observable i poniższych klas specyficznych dla podstawowych elementów, aby można było obserwować pola:

Obserwowalne pola to autonomiczne obserwowalne obiekty, które mają jeden . W przypadku wersji podstawowych unikasz pakowania i unboxingu podczas dostępu. operacji. Aby użyć tego mechanizmu, utwórz właściwość public final w Javie języka programowania lub właściwości tylko do odczytu w Kotlin, jak widać w tagu następujący przykład:

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

Aby uzyskać dostęp do wartości pola, użyj funkcji set() i get() metod akcesora lub użyj właściwości Kotlin :

Kotlin

user.firstName = "Google"
val age = user.age

Java

user.firstName.set("Google");
int age = user.age.get();

Obserwowane kolekcje

Niektóre aplikacje używają dynamicznych struktur do przechowywania danych. Obserwowalne kolekcje pozwalają za pomocą klucza. ObservableArrayMap zajęcia jest przydatny, gdy klucz jest typem odwołania, takim jak String, jak pokazano w następujący przykład:

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

W tym układzie możesz znaleźć mapę za pomocą klawiszy ciągu znaków, jak widać w instrukcjach następujący przykład:

<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"/>

ObservableArrayList jest przydatna, gdy klucz jest liczbą całkowitą w następujący sposób:

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

W układzie możesz uzyskać dostęp do listy za pomocą indeksów, jak widać w tabeli następujący przykład:

<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"/>

Obserwowalne obiekty

Klasa implementująca interfejs Observable umożliwia rejestrację detektorów, którzy chcą otrzymywać powiadomienia o zmianach właściwości z obserwowalnego obiektu.

Interfejs Observable ma mechanizm dodawania i usuwania detektorów, ale określić czas wysyłania powiadomień. Aby ułatwić programowanie, dane Biblioteka powiązań udostępnia BaseObservable, które implementuje mechanizm rejestracji odbiornika. Klasa danych, która implementuje BaseObservable jest odpowiedzialny za powiadamianie o zmianie właściwości. Do zrobienia to, przypisz adnotację Bindable do getteru i wywołaj funkcję notifyPropertyChanged() w metodzie ustawiającej, jak widać w tym przykładzie:

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

Powiązanie danych generuje klasę o nazwie BR w pakiecie modułu, która zawiera identyfikatory zasobów używanych do wiązania danych. Adnotacja Bindable generuje wpis w pliku klasy BR podczas kompilacji. Jeśli klasa bazowa klas danych, których nie można zmienić, możesz zaimplementować interfejs Observable za pomocą PropertyChangeRegistry. w celu skutecznego rejestrowania detektorów i powiadamiania detektorów.

Obiekty rozpoznające cykl życia

Układy w aplikacji mogą też łączyć się ze źródłami wiązań danych, które automatycznie powiadamiać UI o zmianach w danych. Dzięki temu Twoje powiązania będą cyklu życia usługi i aktywowane tylko wtedy, gdy interfejs użytkownika jest widoczny na ekranie.

Obsługa wiązania danych StateFlow i LiveData Więcej informacji na temat: przy użyciu LiveData w wiązaniu danych, zapoznaj się z sekcją Używanie LiveData do powiadamiania interfejsu użytkownika o danych zmian.

Używanie StateFlow

Jeśli Twoja aplikacja używa Kotlin z współrzędnymi, możesz użyć Obiekty jako źródło powiązania danych: StateFlow. Aby użyć obiektu StateFlow z: klasy powiązania, określ właściciela cyklu życia, aby zdefiniować zakres StateFlow obiekt. Ten przykład określa działanie jako właściciel cyklu życia po utworzeniu klasy powiązania:

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
    }
}

Zgodnie z opisem w sekcji Powiąż widoki układu z architekturą Komponenty, powiązanie danych bezproblemowo współpracuje z ViewModel obiektów. StateFlow i ViewModel możesz używać razem w ten sposób:

class ScheduleViewModel : ViewModel() {

    private val _username = MutableStateFlow<String>("")
    val username: StateFlow<String> = _username

    init {
        viewModelScope.launch {
            _username.value = Repository.loadUserName()
        }
    }
}

W układzie przypisz właściwości i metody obiektu ViewModel do odpowiednich widoków za pomocą wyrażeń wiążących, jak pokazano poniżej. przykład:

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

Interfejs aktualizuje się automatycznie po każdej zmianie wartości nazwy użytkownika.

Wyłącz obsługę StateFlow

W przypadku aplikacji korzystających z Kotlin i AndroidaX obsługa StateFlow jest automatycznie włączona w wiązaniu danych. Oznacza to, że zależność współrzędna jest automatycznie dołączane do aplikacji, jeśli zależność nie jest jeszcze dostępna.

Możesz z niej zrezygnować, dodając do swojego konta: Plik build.gradle:

Odlotowe

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

Kotlin

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

Możesz też globalnie wyłączyć StateFlow w projekcie, dodając ten wiersz do pliku gradle.properties:

Odlotowe

android.defaults.databinding.addKtx = false

Kotlin

android.defaults.databinding.addKtx = false

Dodatkowe materiały

Więcej informacji o wiązaniu danych znajdziesz w dodatkowych materiałach poniżej:

Próbki

Ćwiczenia z programowania

Posty na blogu

.