【问题标题】:RxJava CombineLatest Operator triggered only onceRxJava CombineLatest 运算符仅触发一次
【发布时间】:2018-11-01 13:48:14
【问题描述】:

我刚开始使用 MVVM,我陷入了这种奇怪的情况,combineLatest 运算符申请表单验证只被触发一次。

我在 MVC 中的 editTextFileds 上使用了 combineLatest,但从未遇到过这个问题。任何帮助表示赞赏。

我的模型视图类

    public class LoginModel extends BaseObservable {

        public final ObservableField<String> username = new ObservableField<>("");
        public final ObservableField<String> password = new ObservableField<>("");
        public final ObservableField<Boolean> emailError = new ObservableField<>(false);
        public final ObservableField<Boolean> passwordError = new ObservableField<>(false);
public final ObservableField<Boolean> buttonState = new ObservableField<>(false);


        public LoginModel() {
            Observable<Boolean> result = Observable.combineLatest(FieldUtils.toObservable(username), FieldUtils.toObservable(password), new BiFunction<String, String, Boolean>() {

                @Override
                public Boolean apply(String s, String s2) throws Exception {
                      emailError.set(isValidateEmail(s));
                      passwordError.set(isValidPassword(s2));
                    Log.e("Triggered", String.valueOf(isValidateEmail(s) && isValidPassword(s2)));
                    return !(isValidateEmail(s) && isValidPassword(s2));
                }
            });



 result.observeOn(Schedulers.io()).subscribeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Boolean>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(Boolean aBoolean) {
                    Log.e("Result", String.valueOf(aBoolean));
                    buttonState.set(aBoolean);

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });

        }


        private boolean isValidateEmail(String email) {
            String emailPattern = "[a-zA-Z0-9._-]+@[a-z]+\\.+[a-z]+";
            return (email.matches(emailPattern) && !TextUtils.isEmpty(email));
        }

        private boolean isValidPassword(String password) {
            return (!TextUtils.isEmpty(password) && password.length() > 4);
        }

    }

apply() 方法即使输入字段的变化也不会触发

我的 XML 文件

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="user"
            type="delivery.restro.com.ViewModel.LoginModel" />
    </data>

    <RelativeLayout
        android:id="@+id/parent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@mipmap/background"
        tools:ignore="MissingPrefix">

        <!--<include layout="@layout/no_internet" />-->


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:layout_margin="@dimen/Margin_Extra_Large"
            android:orientation="vertical">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="@dimen/activity_horizontal_margin"
                android:src="@mipmap/logo" />

            <EditText
                android:id="@+id/phone"
                android:layout_width="match_parent"
                android:layout_height="@dimen/button_height"
                android:layout_marginBottom="@dimen/activity_horizontal_margin"
                android:background="@drawable/white_view_radius"
                android:hint="@string/editText_hint_phone"
                android:inputType="textEmailAddress"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:text="@{user.username}"
                android:textColor="@android:color/black"
                android:textColorHint="@color/colorDarkGrey"
                app:error="@{user.emailError?@string/error_invalid_email:null}" />
            <!--app:error="@{user.emailError==true?@string/error_invalid_email:null}" />-->

            <EditText
                android:id="@+id/password"
                android:layout_width="match_parent"
                android:layout_height="@dimen/button_height"
                android:layout_marginBottom="@dimen/activity_horizontal_margin"
                android:background="@drawable/white_view_radius"
                android:hint="@string/editText_hint_password"
                android:inputType="textPassword"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:text="@{user.password}"
                android:textColor="@android:color/black"
                android:textColorHint="@color/colorDarkGrey"
                app:error="@{user.passwordError?@string/error_invalid_password:null}" />

            <Button
                android:id="@+id/login"
                android:layout_width="match_parent"
                android:layout_height="@dimen/button_height"
                android:background="@drawable/button_yellow"
                android:enabled="@{user.buttonState}"
                android:text="@string/text_login"
                android:textColor="@android:color/black" />


        </LinearLayout>


    </RelativeLayout>
</layout>

【问题讨论】:

  • 你不应该订阅吗?
  • 它在 FieldUtils.toField(result) 中实现,为了简单起见,我更新了代码 sn-p。

标签: android mvvm rx-java rx-java2 android-databinding


【解决方案1】:

我认为有一种更简单的方法可以通过 RxBindingCombine Latest 运算符与 Text 字段一起使用,并且无需在不同线程上观察,这是仅在进行繁重的操作(例如从服务器获取数据、进行数据库查询等)时才需要。 你可以在这篇文章中了解它

RxBinding

Reactive Forms with RxAndroid

【讨论】:

  • 感谢您的回复。我知道 RxBinding 并在其他项目中使用过它。此应用程序基于 MVVM 架构构建,并使用 ObservableField 分配给 edittext 的文本字段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多