Адаптер привязки наблюдателя текста с ViewModel

Я все еще новичок во всех этих компонентах архитектуры MVVM и Android. У меня есть несколько экранов («Вход» и «Регистрация»), на которых есть ввод для электронной почты, пароля, имени и т. Д., А также кнопка «продолжить», которая активна только тогда, когда обязательные поля заполнены правильно. Также есть текстовые представления для сообщений, таких как «пароль должен быть ...» и «недействительный адрес электронной почты ...». Я пытаюсь использовать адаптер привязки и модель просмотра, чтобы вытащить часть этой логики проверки из моей MainActivity и из моей бизнес-логики, но я борюсь. Я даже не уверен, что это лучший способ сделать это. Я думал, что ViewModel будет удерживать свое состояние при изменении вращения / активности.

RegisterActivity - это действие, которое просто содержит ViewPager с 3 фрагментами (адрес электронной почты / пароль, имя / фамилия, код проверки).

Адаптер для привязки

@BindingAdapter("app:onTextChanged")
public static void onTextChanged(TextInputEditText view, TextViewBindingAdapter.OnTextChanged listener) {

}

Макет

<TextView
            android:id="@+id/tv_error_message"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:text="@string/register_email_requirement"
            android:textColor="@color/moenPrimaryError"
            android:textSize="18sp"
            android:visibility="@{viewModel.emailValidationVisible ? View.VISIBLE: View.GONE}"
            app:layout_constraintBottom_toTopOf="@id/input_layout_password"
            app:layout_constraintEnd_toEndOf="@+id/input_layout_email_address"
            app:layout_constraintStart_toStartOf="@+id/input_layout_email_address"
            app:layout_constraintTop_toBottomOf="@+id/input_layout_email_address"
            app:layout_goneMarginTop="16dp" />

<com.google.android.material.textfield.TextInputEditText
                android:id="@+id/input_email_address"
                style="@style/MoenTextInputEditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textEmailAddress"
                app:onTextChanged="@{viewModel.onTextChanged}"
                app:onFocusChange="@{inputLayoutEmailAddress}">

            </com.google.android.material.textfield.TextInputEditText>

ViewModel

public class RegisterFragmentViewModel extends BaseObservable {
    private boolean emailValidationVisible = false;

    @Bindable
    public boolean getEmailValidationVisible() {
        return this.emailValidationVisible;
    }

    public void toggle() {
        this.emailValidationVisible = !this.emailValidationVisible;
        notifyPropertyChanged(BR.viewModel);
    }

    public void onTextChanged(CharSequence s, int start, int before, int count) {
        Log.w("tag", "onTextChanged " + s);
        this.toggle();
    }
}

Это просто тест, который у меня есть. Я думал, что могу связать видимость TextView с логическим значением, которым я могу переключать / управлять с помощью прослушивателя onTextChanged, но я не знаю, как подключить адаптер привязки. Я на правильном пути? Есть ли лучший / более простой способ сделать это?


person Nelson.b.austin    schedule 02.07.2019    source источник


Ответы (1)


Я на правильном пути? Есть ли лучший / более простой способ сделать это?

это способ сделать это. Я бы удалил тернарный оператор из этой строки

  android:visibility="@{viewModel.emailValidationVisible ? View.VISIBLE: View.GONE}"

и создайте простую функцию в вашей виртуальной машине, которая ее возвращает. НАПРИМЕР:

   @Bindable
   public int getVisibility() {
      return emailValidationVisible ? View.VISIBLE: View.GONE     
   }

и в toggle () у вас будет что-то вроде

 public void toggle() {
    this.emailValidationVisible = !this.emailValidationVisible;
    notifyPropertyChanged(BR.visibility);
}

который вызовет для вас геттер. Ваш xml нужно будет изменить, как показано ниже

  android:visibility="@{viewModel.getVisibility()}"

В качестве альтернативы вы можете создать BindingAdapter, который принимает логическое значение и изменить видимость в соответствии с ним.

person Blackbelt    schedule 02.07.2019