LiveData двусторонняя привязка данных БЕЗ разоблачения MutableLiveData - PullRequest
4 голосов
/ 28 мая 2019

Я пытаюсь использовать двустороннюю привязку данных в EditText, которая прекрасно работает, если я выставляю поле как MutableLiveData, как это обычно видно на примерах, которые я нашел в Интернете.

Однако есть веские причины не раскрывать MutableLiveData, и эти причины магически недействительны, потому что я решил использовать библиотеку привязки данных.

РЕДАКТИРОВАТЬ: основной мотивацией здесь является то, что MyViewModel должен контролировать данные настроек (это причина, почему не рекомендуется выставлять MutableLiveData напрямую), в установщике я могу выполнить любые проверки или преобразования, необходимые, а затем просто позвоните setValue на LiveData.

Я обычно выставляю LiveData геттер и отдельный сеттер от моей ViewModel, я пытался заставить это работать с двусторонним связыванием данных, используя аннотацию InverseMethod(), но это не сработает, потому что привязка данных ищет для обратного метода к getValue() самой LiveData.

Вот простой пример:

public class MyViewModel extends ViewModel {

    private MutableLiveData<String> mEmail = new MutableLiveData<>();

    // @InverseMethod("setEmail")    ### THIS DOESN'T WORK
    public LiveData<String> getEmail() {
        return mEmail;
    }

    // ### I WANT DATA-BINDING TO USE THIS METHOD
    public void setEmail(String email) {
        if (mEmail.getValue() != email) {
            mEmail.setValue(email);
        }
    }
}

и вот как это нужно связать

<EditText
   android:id="@+id/input_email"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:text="@={viewmodel.email}"/>

единственный обходной путь, который работает до сих пор, - это использование односторонней привязки данных для установки текста на EditText, а затем присоединение TextWatcher и вызова оттуда моего ViewModel.setter.

EDIT:
Второй обходной путь - расширить MutableLiveData, а затем выполнить проверки и преобразования в переопределенном setValue ... это много шаблонного для написания.

Ответы [ 2 ]

0 голосов
/ 25 июня 2019

Нам было рекомендовано переключиться с ObservableField на LiveData для привязки данных, поскольку он учитывает жизненный цикл. Мы также рекомендовали не раскрывать MutableLiveData, потому что модель представления должна управлять назначением.

Это прекрасно работает для односторонней привязки данных, и в этих случаях я бы выставлял только LiveData.

Мы хотим использовать двустороннюю привязку данных, которая по определению перемещает назначение из модели представления в пользовательский интерфейс, поэтому я считаю, что в этом случае предоставление MutableLiveData является правильным. Я говорю это, поскольку мы делаем это нарочно, потому что мы хотим, чтобы наш пользовательский интерфейс мог назначать значения, чтобы у нас были более чистые представления.

0 голосов
/ 01 июня 2019

У меня был точно такой же вопрос, вот как я нашел ваш. Я знаю, что это не совсем то, что вы ищете, но можно было бы наблюдать за mEmail из вашей ViewModel и реализовывать в нем свой код setEmail () (после того, как само значение было установлено, конечно ... я не знаете, как управлять настройкой значения, которое вы ищете, я думаю)

val observer = Observer<String> { setEmail(it)}
fun setEmail(value:String){ //Your code }
init{
    mEmail.observeForever(observer)
}
//Don´t forget to remove the observer
...