Przy użyciu jednokierunkowego wiązania danych można określić wartość atrybutu i ustawić detektor, który reaguje na zmianę w tym atrybucie:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@{viewmodel.rememberMe}" android:onCheckedChanged="@{viewmodel.rememberMeChanged}" />
Dwukierunkowe wiązanie danych skraca ten proces:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@={viewmodel.rememberMe}" />
Zapis @={}, który zawiera znak „=” podpisać, otrzymuje dane
wprowadzasz w nim zmiany w usłudze, jednocześnie nasłuchując aktualizacji użytkowników.
Aby reagować na zmiany w danych zapasowych, możesz ustawić układ
implementację zmiennej Observable, zwykle
BaseObservable i użyj
Adnotacja @Bindable, jak w tym miejscu
ten fragment kodu:
Kotlin
class LoginViewModel : BaseObservable { // val data = ... @Bindable fun getRememberMe(): Boolean { return data.rememberMe } fun setRememberMe(value: Boolean) { // Avoids infinite loops. if (data.rememberMe != value) { data.rememberMe = value // React to the change. saveData() // Notify observers of a new value. notifyPropertyChanged(BR.remember_me) } } }
Java
public class LoginViewModel extends BaseObservable { // private Model data = ... @Bindable public Boolean getRememberMe() { return data.rememberMe; } public void setRememberMe(Boolean value) { // Avoids infinite loops. if (data.rememberMe != value) { data.rememberMe = value; // React to the change. saveData(); // Notify observers of a new value. notifyPropertyChanged(BR.remember_me); } } }
Metoda pobierania właściwości możliwej do powiązania nazywa się getRememberMe(), więc funkcja
odpowiednia metoda ustawiająca właściwości automatycznie używa nazwy
setRememberMe()
Więcej informacji o korzystaniu z BaseObservable i @Bindable znajdziesz w artykule Praca z:
obserwowalne obiekty danych.
Dwukierunkowe wiązanie danych za pomocą atrybutów niestandardowych
Platforma udostępnia implementacje dwukierunkowego wiązania danych dla najczęstszych
atrybutów dwukierunkowych i zmieniać detektory, których możesz używać
jako część aplikacji. Jeśli chcesz użyć dwukierunkowego wiązania danych z niestandardowym
musisz pracować z atrybutami
@InverseBindingAdapter.
oraz
@InverseBindingMethod.
adnotacji.
Jeśli na przykład chcesz włączyć dwukierunkowe wiązanie danych dla atrybutu "time"
w widoku niestandardowym MyView wykonaj te czynności:
- Dodaj adnotację do metody, która ustawia wartość początkową, i aktualizuje się, gdy wartość zmienia się za pomocą parametru - @BindingAdapter:- Kotlin- @BindingAdapter("time") @JvmStatic fun setTime(view: MyView, newValue: Time) { // Important to break potential infinite loops. if (view.time != newValue) { view.time = newValue } } - Java- @BindingAdapter("time") public static void setTime(MyView view, Time newValue) { // Important to break potential infinite loops. if (view.time != newValue) { view.time = newValue; } } 
- Dodaj adnotację do metody, która odczytuje wartość z widoku, za pomocą - @InverseBindingAdapter:- Kotlin- @InverseBindingAdapter("time") @JvmStatic fun getTime(view: MyView) : Time { return view.getTime() } - Java- @InverseBindingAdapter("time") public static Time getTime(MyView view) { return view.getTime(); } 
Na tym etapie wiązanie danych wie, co zrobić, gdy dane ulegną zmianie (wywołuje metodę
metoda z adnotacją
@BindingAdapter) i co robić
po zmianie atrybutu view (wywołanie funkcji
InverseBindingListener).
Nie wie jednak, kiedy ani w jaki sposób atrybut się zmienia.
Żeby to zrobić, musisz ustawić detektor w widoku. Może to być niestandardowy detektor
może być to zdarzenie o charakterze ogólnym, takie jak utrata
ostrość lub zmiana tekstu. Dodaj adnotację @BindingAdapter do metody
który ustawia detektor zmian usługi:
Kotlin
@BindingAdapter("app:timeAttrChanged") @JvmStatic fun setListeners( view: MyView, attrChange: InverseBindingListener ) { // Set a listener for click, focus, touch, etc. }
Java
@BindingAdapter("app:timeAttrChanged") public static void setListeners( MyView view, final InverseBindingListener attrChange) { // Set a listener for click, focus, touch, etc. }
Detektor zawiera parametr InverseBindingListener. Korzystasz z
InverseBindingListener, aby poinformować system wiązań danych, że atrybut
została zmieniona. System może wtedy zacząć wywoływać metodę opisaną za pomocą
@InverseBindingAdapter itd.
W praktyce ten odbiornik zawiera nieproste zasady logiczne,
do jednokierunkowego wiązania danych. Zobacz przykładowy adapter atrybutu tekstowego
zmień,
TextViewBindingAdapter
Użytkownicy dokonujący konwersji
Jeśli zmienna powiązana z obiektem View
muszą zostać sformatowane, przetłumaczone lub zmienione przed wyświetleniem,
można użyć obiektu Converter.
Weźmy na przykład obiekt EditText z datą:
<EditText
    android:id="@+id/birth_date"
    android:text="@={Converter.dateToString(viewmodel.birthDate)}"
/>
Atrybut viewmodel.birthDate zawiera wartość typu Long, więc wymaga
do sformatowania za pomocą konwertera.
Ponieważ używane jest wyrażenie dwukierunkowe, wymagana jest również odwrotność
konwertera, aby poinformować bibliotekę, jak z powrotem przekonwertować ciąg znaków podany przez użytkownika.
do typu danych kopii zapasowej, w tym przypadku Long. W tym celu dodaj
adnotacja @InverseMethod,
do jednego z konwerterów i umieść tę adnotację w odwrotnej wartości
konwerter Przykładowa konfiguracja znajduje się w kodzie poniżej
snippet:
Kotlin
object Converter { @InverseMethod("stringToDate") @JvmStatic fun dateToString( view: EditText, oldValue: Long, value: Long ): String { // Converts long to String. } @JvmStatic fun stringToDate( view: EditText, oldValue: String, value: String ): Long { // Converts String to long. } }
Java
public class Converter { @InverseMethod("stringToDate") public static String dateToString(EditText view, long oldValue, long value) { // Converts long to String. } public static long stringToDate(EditText view, String oldValue, String value) { // Converts String to long. } }
Pętle nieskończone przy użyciu dwukierunkowego wiązania danych
Pamiętaj, aby podczas korzystania z dwukierunkowego wiązania danych nie wprowadzać zapętleń nieskończonych. Kiedy
użytkownik zmieni atrybut, metoda opisana za pomocą
Funkcja @InverseBindingAdapter jest wywoływana, a wartość jest przypisana do kopii zapasowej
usłudze. To z kolei wywoła metodę opisaną przy użyciu
@BindingAdapter, które spowodowałoby kolejne wywołanie metody opisanej w adnotacjach.
przy użyciu @InverseBindingAdapter itd.
Z tego powodu ważne jest przerywanie możliwych pętli nieskończonych, porównując
nowe i stare wartości w metodach oznaczonych za pomocą @BindingAdapter.
Atrybuty dwukierunkowe
Platforma zapewnia wbudowaną obsługę dwukierunkowego wiązania danych atrybuty z poniższej tabeli. Szczegółowe informacje na temat tego, jak platforma zapewnia tutaj znajdziesz instrukcje implementacji odpowiednich adapterów wiązań:
| Kategoria | Atrybuty | Adapter wiązania | 
|---|---|---|
| AdapterView | android:selectedItemPositionandroid:selection | AdapterViewBindingAdapter | 
| CalendarView | android:date | CalendarViewBindingAdapter | 
| CompoundButton | android:checked | CompoundButtonBindingAdapter | 
| DatePicker | android:yearandroid:monthandroid:day | DatePickerBindingAdapter | 
| NumberPicker | android:value | NumberPickerBindingAdapter | 
| RadioButton | android:checkedButton | RadioGroupBindingAdapter | 
| RatingBar | android:rating | RatingBarBindingAdapter | 
| SeekBar | android:progress | SeekBarBindingAdapter | 
| TabHost | android:currentTab | TabHostBindingAdapter | 
| TextView | android:text | TextViewBindingAdapter | 
| TimePicker | android:hourandroid:minute | TimePickerBindingAdapter | 
Dodatkowe materiały
Aby dowiedzieć się więcej o wiązaniu danych, zapoznaj się z tymi artykułami z dodatkowymi zasobami.
Próbki
Ćwiczenia z programowania
Posty na blogu
Polecane dla Ciebie
- Uwaga: tekst linku wyświetla się, gdy JavaScript jest wyłączony
- Praca z obserwowalnymi obiektami danych
- Układy i wyrażenia wiążące
- Powiąż widoki układu z komponentami architektury
