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