RxBinding TextChanges не будет продолжать испускать текстовые изменения

Попытка выяснить, почему RxTextView.textChanges выдает только начальное значение. Насколько я понимаю, он должен генерировать все новые текстовые изменения в нижестоящих подписках.

Вот код

    public class SignupFragment extends Fragment {

    @BindView(R.id.text_name) EditText txtName;
    @BindView(R.id.text_email) EditText txtEmail;
    @BindView(R.id.text_password) EditText txtPassword;
    @BindView(R.id.text_confirm_password) EditText txtConfirmPassword;
    @BindView(R.id.btn_signup) Button btnSignup;
    SignupViewModel viewModel;
    private CompositeDisposable disposables;

    FragmentSignupBinding binding;
    @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_signup, container, false);
        ButterKnife.bind(this, view);
        this.disposables = new CompositeDisposable();

        RxTextView.textChanges(txtEmail)
                .subscribe(new Observer<CharSequence>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(CharSequence charSequence) {
                        Log.d("Subscription", charSequence.toString());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {
                        Log.d("Subscription", "On Complete");
                    }
                });

        viewModel = ViewModelProviders.of(this).get(SignupViewModel.class);
        viewModel.applyInputs(RxTextView.textChanges(txtName),
                RxTextView.textChanges(txtEmail),
                RxTextView.textChanges(txtPassword),
                RxTextView.textChanges(txtConfirmPassword),
                RxView.clicks(btnSignup));


        Disposable validInputs =
        viewModel.validInputs()
                .doOnNext(new Consumer<Boolean>() {
                    @SuppressLint("TimberArgCount")
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        Timber.d("Valid inputs: %b", aBoolean.booleanValue());
                    }
                })
                .subscribe(RxView.visibility(btnSignup));

        disposables.add(validInputs);

        FragmentSignupBinding binding = FragmentSignupBinding.inflate(inflater, container, false);
        return binding.getRoot();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.disposables.dispose();
    }
}

Ранее это было отредактировано, чтобы сосредоточиться на том, где, как я думал, была проблема. Теперь это полная картина.


person Evan Anger    schedule 06.01.2018    source источник
comment
выглядит нормально для меня, можете ли вы опубликовать полный код?   -  person ESala    schedule 06.01.2018
comment
Добавлен полный код фрагмента. Только упустил вещи, поскольку я пытался упростить код. Конечное состояние. Я хочу, чтобы эти наблюдаемые были отправлены в модель представления.   -  person Evan Anger    schedule 06.01.2018


Ответы (3)


Я неправильно обрабатывал привязку данных фрагмента. В этот момент в коде это даже не было необходимо. Я не понимал, что установка может повлиять на RxBindings.

Следующий код был сломан...

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_signup, container, false);
...

        FragmentSignupBinding binding = FragmentSignupBinding.inflate(inflater, container, false);
        return binding.getRoot();
    }

Следующий код работает сейчас....

    @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        FragmentSignupBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_signup, container, false);
        View view = binding.getRoot();
        ButterKnife.bind(this, view);
        this.disposables = new CompositeDisposable();
....
        return view;
    } 
person Evan Anger    schedule 07.01.2018

    RxTextView.textChanges(txtEmail)
            .subscribe(new Observer<CharSequence>() {

Это неправильно, должно быть

disposables.add(RxTextView.textChanges(txtEmail)
        .subscribe(new DisposableObserver<CharSequence>() {

Кроме того, RxView.clicks(, например, может поддерживать только 1 слушателя, потому что он является оберткой для метода setOnClickListener().

Так что есть большая вероятность, что ваш код будет работать так

Observable<CharSequence> obsName;

...
public void onCreate(...) {
    ...
    obsName = RxTextView.textChanges(txtName).share();

а затем используйте obsName где угодно, то же самое для других вызовов Rx___, которые у вас есть.

person EpicPandaForce    schedule 10.01.2018
comment
Это абсолютно точно, и именно так теперь выглядит код, но проблема возникла не из-за этого. На самом деле это не имело никакого отношения к тому, как я настраивал наблюдаемые, и больше к тому, как я, как ни странно, настраивал фактический Фрагмент. - person Evan Anger; 14.01.2018
comment
Я все еще отмечаю это только потому, что думаю, что это все еще актуально для улучшения кода и избавления от этой категоризации проблем, которые могут пойти не так. - person Evan Anger; 14.01.2018

Я думаю, что у вас может быть только 1 наблюдаемое для каждого типа события.

Добавление второго, как в вашем случае, удаляет предыдущий.

Попробуйте закомментировать все, кроме одного RxTextView.textChanges(txtEmail).

См. обсуждение этой проблемы: только один наблюдаемый объект за раз?

person ESala    schedule 06.01.2018
comment
Да, я удалил другие выбросы textChange безрезультатно. Просмотр следующее, которое кажется популярным и на которое часто ссылаются в качестве примера. - person Evan Anger; 07.01.2018
comment
Кстати, возвращаясь к этому совсем недавно, RxTextView.textChanges может иметь несколько наблюдаемых, вам просто нужен оператор общего доступа, чтобы разрешить несколько подписок. Если у вас есть два использования textChanges для одного и того же представления, с этим возникают проблемы. - person Evan Anger; 14.01.2018
comment
@EvanAnger да, я думаю, у вас может быть только одна наблюдаемая, потому что добавление большего количества очищает предыдущие. Как вы сказали, лучший способ решить эту проблему - создать только один наблюдаемый объект и поделиться им, а не создавать несколько, как в вашем вопросе. - person ESala; 15.01.2018