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:selectedItemPosition android:selection | AdapterViewBindingAdapter |
CalendarView | android:date | CalendarViewBindingAdapter |
CompoundButton | android:checked | CompoundButtonBindingAdapter |
DatePicker | android:year android:month android: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:hour android: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