Привязка Адаптер Текст Наблюдатель с ViewModel - PullRequest
0 голосов
/ 02 июля 2019

Я все еще новичок во всех этих компонентах архитектуры MVVM и Android. У меня есть несколько экранов («Войти» и «Зарегистрироваться»), в которых есть данные для ввода адреса электронной почты, пароля, имени и т. Д., А также кнопка «Продолжить», которая активируется только тогда, когда необходимые поля заполнены правильно. Есть также текстовые представления для сообщений, таких как «пароль должен быть ...» и «недействительный адрес электронной почты ...». Я пытаюсь использовать связывающий адаптер и viewmodel, чтобы вытащить часть этой логики проверки из моей 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, но я не знаю, как подключить адаптер связывания. Я на правильном пути? Есть ли лучший / более простой способ сделать это?

1 Ответ

0 голосов
/ 02 июля 2019

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

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

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

и создайте простую функцию в вашей виртуальной машине, которая ее возвращает. EG:

   @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, который принимает логическое значение и соответственно изменять видимость для него

...