Evan Anger
Evan Anger

Reputation: 714

RxBinding TextChanges won't continue emitting text changes

Trying to figure out why RxTextView.textChanges only emits the initial value. My understanding is that it should emit all new text changes to downstream subscriptions.

Here is the code

    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();
    }
}

This previously was edited down to focus on where I thought the issue was. This is now the complete picture.

Upvotes: 1

Views: 2415

Answers (3)

EpicPandaForce
EpicPandaForce

Reputation: 81549

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

This is wrong, should be

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

Also, RxView.clicks( for example can support only 1 listener, because it wraps setOnClickListener() method.

So there is a good chance that your code would work like so

Observable<CharSequence> obsName;

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

and then use obsName wherever, same for the other Rx___ calls you have.

Upvotes: 1

Evan Anger
Evan Anger

Reputation: 714

I wasn't handling the Fragment Data Binding correctly. At this point in the code it wasn't even necessary. I didn't realize that setup could affect the RxBindingings.

Following code was broken...

 @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();
    }

Following code works now....

    @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;
    } 

Upvotes: 2

ESala
ESala

Reputation: 7058

I think that you can only have 1 observable per event type.

Adding a second one like in your case removes the previous one.

Try commenting out everything but one RxTextView.textChanges(txtEmail).

See the discussion on this issue: only one observable at a time?

Upvotes: 0

Related Questions