Dwukierunkowe wiązanie danych

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:

  1. 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;
        }
    }
  2. 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

. .