JakeWharton / RxBinding

RxJava binding APIs for Android's UI widgets.
Apache License 2.0
9.69k stars 971 forks source link

only one observable at a time? #146

Open adennie opened 9 years ago

adennie commented 9 years ago

I'm JUST dipping my toes into RxBinding; looks very promising for my current project. Initially I'm interested in using it for some form field validation. I see a lot of comments in the code saying "Only one observable can be used for a view at a time". By that, do you mean only one observable of a particular kind, or only one observable, period? For example, I have a login screen with username and password TextViews. I'd like to observe the text values entered into the username field via RxTextView.textChanges and simultaneously observe that same field losing focus via RxView.focusChanges. This way, I can capture the username as it is being entered, and then when the user changes focus to the password field, I can validate the entered username and flag any problems (too short, invalid chars, etc.). Can I have both of these observables bound to the same TextView at the same time, or is that not going to work?

P.S. is there any discussion forum yet for RxBinding? I couldn't find anything.

JakeWharton commented 9 years ago

It's only one instance per view listener. If you do RxView.clicks twice on the same view, only the second one will actually receive events.

We can improve the wording.

xfumihiro commented 9 years ago

@JakeWharton Should we add warning/debug logs on these occasions?

JakeWharton commented 9 years ago

How would you detect it? A strict mode-like feature would be interesting, but it's not easy to consume debug versions of libraries as remote dependencies.

On Fri, Sep 18, 2015, 10:26 AM Fumihiro Xue notifications@github.com wrote:

@JakeWharton https://github.com/JakeWharton Should we add warning/debug logs on these occasions?

— Reply to this email directly or view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146#issuecomment-141467410 .

xfumihiro commented 9 years ago

What about using bytecode injection? Just like Hugo, we could add annotations to the bindings that use "set listener methods" behind the scene and detect if it get subscribed more than once.

xfumihiro commented 8 years ago

Basically we just add Exclusive annotations on those and if they're subscribed more than once at a time without being unsubscribed first, show a warning message on the log. Here's a done and tested fork.

xfumihiro commented 8 years ago

As for strict-mode kind of solutions, I cannot think of any thing that's nice and clean. Should I just send a PR on this?

JakeWharton commented 8 years ago

Let me get caught up on other PRs before we take this further. I've been busy on other things and need to clean out some backlog first.

On Mon, Sep 21, 2015, 7:41 PM Fumihiro Xue notifications@github.com wrote:

As for strict-mode kind of solutions, I cannot think of any thing that's nice and clean. Should I just send a PR on this https://github.com/JakeWharton/RxBinding/compare/master...xfumihiro:feature/debug-aop?expand=1 ?

— Reply to this email directly or view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146#issuecomment-142138671 .

egslava commented 8 years ago

Why not just implement multiple listeners? :-) It would be very comfortable to use (Kotlin):

pass.focusChanges().bindToLifecycle(this).subscribe {
...
}

So it would be just like usual events but with multiple listeners support :-)

JakeWharton commented 8 years ago

Because 99% of the time you only need one and I don't want the overhead of multiple listener support for all those cases just to support a 1% use. You can use RxJava's built-in mechanisms for sharing observables to support multiple subscribers.

JakeWharton commented 7 years ago

I have a zero-overhead plan to fix this. Hoping to get something prototyped soon.

JakeWharton commented 7 years ago

Well, zero-overhead in the common (single observer) case.

marcinsus commented 7 years ago

In some of cases rxBinging allows to multiple observable at a time eg. when we internally use addListener instead setListener. Maybe we should mention it in javaDoc or create annotation for it.

JakeWharton commented 7 years ago

There is already an issue tracking that.

On Fri, Dec 9, 2016 at 12:06 PM marcinsus notifications@github.com wrote:

In some of cases rxBinging allows to multiple observable at a time eg. when we internally use addListener instead setListener. Maybe we should mention it in javaDoc or create annotation for it.

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146#issuecomment-266066636, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEfWe7qLrWN6IeSuFzXbsxBPGQZBsks5rGYqTgaJpZM4F-uDB .

Sirelon commented 7 years ago

As a workaround you can use hot observable.

private PublishSubject<Object> clickObservable = PublishSubject.create(); RxView.clicks(view).subscribe(clickObservable);

And use clickObservable.subscribe() many times

JakeWharton commented 7 years ago

Call .share() on the returned observable. Using a subject is wasteful here.

On Wed, Feb 8, 2017 at 10:28 AM Alexandr notifications@github.com wrote:

As a workaround you can use hot observable.

private PublishSubject clickObservable = PublishSubject.create(); RxView.clicks(view).subscribe(clickObservable);

And use clickObservable.subscribe() many times

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146#issuecomment-278360140, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEQN9a2v-nRtSPoOr1zOZe1HKU-SVks5rad8lgaJpZM4F-uDB .

eboudrant commented 6 years ago

Actually I got a use case on a seek view where multiple subscription would make sense and not sure how to deal with it, ideally I wanted :

seekview.changeEvents().filter({ start event }).subscribe { pause video player }
seekview.userChanges().subscribe { update our fancy ui with a preview image }
seekview.changeEvents().filter({ end event }).subscribe { seek to position video player }

It does not works as only the last subscribe works. Not sure how to do it except by only listening changes() and process different events by storing a state.

JakeWharton commented 6 years ago

Call publish(), set up your multiple subscriptions, and then call connect(). Or you can use .share() so long as all the subscriptions are made right away.

On Thu, Oct 12, 2017, 2:37 PM Emmanuel Boudrant notifications@github.com wrote:

Actually I got a use case on a seek view where multiple subscription would make sense and not sure how to deal with it, ideally I wanted :

seekview.changes().filter({ start event }).subscribe { pause video player } seekview.userChanges().subscribe { update our fancy ui with a preview image } seekview.changes().filter({ end event }).subscribe { seek to position video player }

It does not works as only the last subscribe works. Not sure how to do it except by only listening changes() and process different events by storing a state.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146#issuecomment-336227770, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEaXqR28esYWy8zJJAQXBU4J29bIPks5srlxggaJpZM4F-uDB .

nikialeksey commented 5 years ago

@JakeWharton Hey! Let's look at this samples:

Observer<Object> one = ...;
Observer<Object> two = ...;

final Observable<Unit> clicks = RxView.clicks(view);

clicks.subscribe(one);
clicks.subscribe(two);
Observer<Object> one = ...;
Observer<Object> two = ...;

final Observable<Unit> clicks = RxView.clicks(view).share();

clicks.subscribe(one);
clicks.subscribe(two);

And I am sure, that the first case is more readable and clearer. But now we need to use second because it works. I created the pull request #500 to solve this problem without .share() or other workarounds. And I can make a general solution for all similar cases. What you think about it?

dubeyvivek57 commented 4 years ago

Can we add RxView.clicks() and RxView.longClicks() on a same view with same time.

JakeWharton commented 4 years ago

Yes

On Tue, Dec 3, 2019, 3:11 AM dubeyvivek57 notifications@github.com wrote:

Can we add RxView.clicks() and RxView.longClicks() on a same view with same time.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146?email_source=notifications&email_token=AAAQIEMGYFY4KZMVCZVP67DQWYICJA5CNFSM4BP24DA2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEFYPBYA#issuecomment-561049824, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAQIEI7IQVN66KCRIA4RELQWYICJANCNFSM4BP24DAQ .