Je suis nouveau en programmation réactive. J'ai donc un problème lors de la création d'un flux à partir d'un événement, comme onClick, ontouch ...
Quelqu'un peut-il m'aider à résoudre ce problème.
Merci.
Vous feriez quelque chose comme ceci:
Observable<View> clickEventObservable = Observable.create(new Observable.OnSubscribe<View>() {
@Override
public void call(final Subscriber<? super View> subscriber) {
viewIWantToMonitorForClickEvents.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (subscriber.isUnsubscribed()) return;
subscriber.onNext(v);
}
});
}
});
// You can then apply all sorts of operation here
Subscription subscription = clickEventObservable.flatMap(/* */);
// Unsubscribe when you're done with it
subscription.unsubscribe();
Puisque vous utilisez Android alors vous pouvez déjà inclure la contrib rxjava-Android
dépendance désormais appelée ioreactivex:rxandroid
. Ils ont déjà une classe pour faciliter cela. La méthode est ViewObservable.clicks
. Vous pouvez l'utiliser comme ça.
Observable<View> buttonObservable = ViewObservable.clicks(initiateButton, false);
buttonObservable.subscribe(new Action1<View>() {
@Override
public void call(View button) {
// do what you need here
}
});
Edit: Depuis la version 1.x, ViewObservable
et de nombreuses classes d'assistance sont supprimées de RxAndroid . Vous aurez besoin de bibliothèque RxBinding à la place.
Observable<Void> buttonObservable = RxView.clicks(initiateButton);
buttonObservable.subscribe(new Action1<Void>() {
@Override
public void call(Void x) {
// do what you need here
}
});
Pour Android, jetez un œil à Jake Wharton RxBindings . Par exemple, il vous permet de créer un événement observable et de vous abonner aux événements de clic avec:
RxView.clicks(myButton)
.subscribe(new Action1<Void>() {
@Override
public void call(Void aVoid) {
/* do something */
}
});
ou, mieux encore, avec des expressions lambda (en utilisant soit Kotlin , Java 8 ou Retrolambda ):
RxView.clicks(myButton)
.subscribe(aVoid -> /* do something */);
Si vous utilisez Kotlin, il convient de noter que RxBindings fournit également fonctions d'extension Kotlin qui vous permettent d'appliquer chaque fonction de liaison directement sur le type cible.
Vous pouvez utiliser un sujet.
Un Subject est une sorte de pont ou de proxy qui agit à la fois comme abonné et comme observable. Parce que c'est un abonné, il peut s'abonner à un ou plusieurs observables, et parce qu'il est observable, il peut passer à travers les éléments qu'il observe en les réémettant, et il peut également émettre de nouveaux éléments.
public class Events {
public static PublishSubject <Object> myEvent = PublishSubject.create ();
}
Lorsque vous souhaitez publier quelque chose
Events.myEvent.onNext(myObject);
Lorsque vous souhaitez recevoir un événement
Events.myEvent.subscribe (...);
** L'utilisation des composants d'architecture LiveData est meilleure car elle gère le cycle de vie et l'activité ou le fragment et vous n'avez pas à vous soucier de vous désabonner des événements car elle observe le cycle de vie des composants ui.
MutableLiveData<Object> event = new MutableLiveData<>();
quand tu veux publier quelque chose
event.postValue(myObject);
Quand vous souhaitez recevoir et événement
event.observe(lifeCycleOwner, (myObject)->...);
Utilisation de RxJava 2:
return Observable.create(new ObservableOnSubscribe<View>() {
@Override
public void subscribe(ObservableEmitter<View> e) throws Exception {
clickView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
e.setCancellable(new Cancellable() {
@Override
public void cancel() throws Exception {
view.setOnClickListener(null);
}
});
e.onNext(view); // Or whatever type you're observing
}
});
}
});
Semble beaucoup plus agréable en utilisant des lambdas:
return Observable.create(new ObservableOnSubscribe<View>() {
@Override
public void subscribe(ObservableEmitter<View> e) throws Exception {
keypad.setOnClickListener(view -> {
e.setCancellable(() -> view.setOnClickListener(null));
e.onNext(view);
});
}
});
Ou utilisez simplement RxBinding comme indiqué par d'autres.
Ma solution ci-dessus est un modèle assez général pour envelopper les auditeurs dans un observable.
Vous pouvez le faire facilement avec Kotlin en utilisant des fonctions d'extension. Par exemple, vous écrivez une fonction d'extension comme celle-ci:
fun View.observableClickListener(): Observable<View> {
val publishSubject: PublishSubject<View> = PublishSubject.create()
this.setOnClickListener { v -> publishSubject.onNext(v) }
return publishSubject
}
Et vous utiliseriez cette extension comme ceci:
viewIWantToObserveClicks.observableClickListener().subscribe()