-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add OperatorAdapterViewOnItemClick to observe OnItemClick events in AdapterViews. Resolve #19. #20
Conversation
…dapterViews. Resolve #19.
LGTM, but I think we should make an agreement on
I really like the idea of public static <T extends View> Observable<OnClickEvent<T>> clicks(final T view, final boolean emitInitialValue);
public static <T extends TextView> Observable<OnTextChangeEvent<T>> text(final T view, final boolean emitInitialValue);
public static <T extends CompoundButton> Observable<OnCheckedChangeEvent<T>> input(final T view, final boolean emitInitialValue);
public class OnClickEvent<T extends View> {
public final T view;
}
public class OnTextChangeEvent<T extends TextView> {
public final T view;
public final CharSequence text;
}
public class OnCheckedChangeEvent<T extends CompoundButton> {
public final T view;
public final boolean value;
} I know, it's a breaking change, but Any thoughts? /cc @mttkay |
@mironov-nsk that sounds sensible. I have to say we don't use RxJava on the view level very much, so I'll let you guys drive the discussion, but I think it's a good idea what you propose. I'm fine with breaking changes on the road to 1.0; the whole idea behind breaking out the contrib module from core was to have independent roadmaps. There's no urgency to rush any of this from my point of view. RxJava had many breaking changes over the last year and a half on its way to 1.0. That's only expected. |
@mironov-nsk events convention looks better than
Also we should do something with |
@naghtarr I'm also wondering if events should be generics or not. |
@mironov-nsk |
Cleaned up generics as discussed. Moved to package rx.android.operators. Made OnItemClickEvent class non-final. Changes are consisted with #22. |
} | ||
|
||
private static class CachedListeners { | ||
private static final Map<AdapterView<?>, CompositeOnClickListener> sCachedListeners = new WeakHashMap<AdapterView<?>, CompositeOnClickListener>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering, are we just being defensive here? As far as I understand, unsubscribing removes a listener already, so why use weak references?
Also, I don't think this should be static, as this means we're sharing mutable state with multiple instances of this class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mttkay We're not defensive here, this is the only way I found to make multiple subscriptions work. There are two problems here:
- Methods like
setOnClickListener
andsetOnItemClickListener
allow to set only one listener, making multiple subscriptions hard to implement. This is the reason we need classes likeCompositeOnClickListener
. - There is no way to get a
OnXXXListener
attached to theView
(since there are nogetOnXXXListener
methods), so we need to save listeners somewhere else.View.setTag(Object tag)
is not an option here since it's heavily used by the end developers.View.setTag(int key, Object key)
could be a solution, but it requires a key to be declared in the resources, making it impossible to ship the library as ajar
.
The only working solution I found is to store CompositeXXXListeners
in the global WeekHasMap
(it have to be static
). Any other ideas how to solve this problem are welcome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand. Are you expecting that this operator is called multiple times for different listeners, i.e. will call
be executed more than once on the same observable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the question why it have to be a WeakHashMap
. Well, it could be just a usual HashMap
, but in this case user have to unsubscribe from the Observable
in order to prevent memory leaks, making the usage of ViewObservables
a bit more complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand. Are you expecting that this operator is called multiple times for different listeners, i.e. will call be executed more than once on the same observable?
Yes, call
will be executed more than once if user subscribes to the Observable
multiple times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making it a hot observable? Why not deal with this using a built in operator like publish? Then you can have multiple subscribers for the same OnClick event
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it could be a hot Observable
, but we still need somehow to attach the Observable
to the View
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a naive standpoint, I would expect it to work like this:
ConnectableObservable source = sourceSequence.lift(new OperatorAdapterViewOnItemClick(listView)).publish();
source.connect();
source.subscribe(o1);
source.subscribe(o2);
but I might be missing something
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point here is to make all this complicity transparent to the end developers. I don't think it's a good idea to force them to use ConnectableObservable
instead of providing the same functionality out of the box.
By the way, OperatorAdapterViewOnItemClick
is not a real Operator
, since it implements OnSubscribe
interface, but not the Operator
one. Probably we should follow the conventions used in RxJava
and name it something like OnSubscribeViewOnItemClick
(and rename all other "operators" as well).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably we should follow the conventions used in RxJava and name it something like OnSubscribeViewOnItemClick (and rename all other "operators" as well).
@mironov-nsk Agreed. But I think we should implement this in separate PR.
Cool. Is this ready to land? |
@mttkay Yes. |
Sorry, landing another PR made this unmergeable. Will merge after this is resolved! |
@mttkay, Merged 0.x changes to this branch. |
👍 |
Add OperatorAdapterViewOnItemClick to observe OnItemClick events in AdapterViews. Resolve #19.
OperatorAdapterViewOnItemClick
to handle onItemClick events from AdapterViews;OnItemClickEvent
class to observe it;itemClicks
method atViewObservable
;