如何从 OnClick 事件 Android 创建一个 Observable?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25457737/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create an Observable from OnClick Event Android?
提问by Thanh Le
I'm new in reactive programming. So I have problem when create a stream from an Event, like onClick, ontouch...
我是反应式编程的新手。所以我在从事件创建流时遇到问题,比如 onClick、ontouch ...
Can anyone help me solve this problem.
谁能帮我解决这个问题。
Thanks.
谢谢。
回答by Miguel Lavigne
You would do something like this:
你会做这样的事情:
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();
Since you're using Android then you may already include the contrib rxjava-android
dependency now known as ioreactivex:rxandroid
.
They already have a class to facilitate this. The method is ViewObservable.clicks
. You can use it like so.
由于您使用的是 Android,因此您可能已经包含了rxjava-android
现在称为ioreactivex:rxandroid
. 他们已经有一个课程来促进这一点。方法是ViewObservable.clicks
。你可以像这样使用它。
Observable<View> buttonObservable = ViewObservable.clicks(initiateButton, false);
buttonObservable.subscribe(new Action1<View>() {
@Override
public void call(View button) {
// do what you need here
}
});
Edit: Since version 1.x, ViewObservable
and many helper classes are removedfrom RxAndroid. You will need RxBinding libraryinstead.
编辑:从 1.x 版开始,ViewObservable
许多助手类已从RxAndroid中删除。您将需要RxBinding 库。
Observable<Void> buttonObservable = RxView.clicks(initiateButton);
buttonObservable.subscribe(new Action1<Void>() {
@Override
public void call(Void x) {
// do what you need here
}
});
回答by Matt
For Android development, have a look at Jake Wharton's RxBindings. For example, it allows you to create an observable and subscribe to click events with:
对于 Android 开发,请查看 Jake Wharton 的RxBindings。例如,它允许您创建一个 observable 并订阅点击事件:
RxView.clicks(myButton)
.subscribe(new Action1<Void>() {
@Override
public void call(Void aVoid) {
/* do something */
}
});
or, even better, with lambda expressions (using either Kotlin, Java 8or Retrolambda):
或者,甚至更好,使用 lambda 表达式(使用Kotlin、Java 8或Retrolambda):
RxView.clicks(myButton)
.subscribe(aVoid -> /* do something */);
If you're using Kotlin, it's worth noting that RxBindings also provides Kotlin extension functionsthat allow you to apply each binding function directly on the target type.
如果您使用的是 Kotlin,值得注意的是,RxBindings 还提供了Kotlin 扩展函数,允许您将每个绑定函数直接应用于目标类型。
回答by Roger Garzon Nieto
You could use a Subject.
您可以使用主题。
A Subjectis a sort of bridge or proxy that acts both as an Subscriber and as an Observable. Because it is a Subscriber, it can subscribe to one or more Observables, and because it is an Observable, it can pass through the items it observes by reemitting them, and it can also emit new items.
一个主题是一种桥或代理的是同时作为用户和可观察到的。因为是Subscriber,所以可以订阅一个或多个Observable,因为是Observable,所以可以通过重新发送观察到的项目,也可以发送新的项目。
public class Events {
public static PublishSubject <Object> myEvent = PublishSubject.create ();
}
When you want to publish something
当你想发表一些东西时
Events.myEvent.onNext(myObject);
When you want to receive an event
当您想接收事件时
Events.myEvent.subscribe (...);
Edit
编辑
**Using Architecture Components LiveData is better because it handles the lifecycle of and activity or fragment and you don't have to worried about unsubscribe from events because it observe the ui components lifecycle.
**使用架构组件 LiveData 更好,因为它处理活动或片段的生命周期,您不必担心取消订阅事件,因为它观察 ui 组件的生命周期。
MutableLiveData<Object> event = new MutableLiveData<>();
when you want to publish something
当你想发表一些东西时
event.postValue(myObject);
When you want to receive and event
当你想接收和事件
event.observe(lifeCycleOwner, (myObject)->...);
回答by Kavi
Using RxJava 2:
使用 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
}
});
}
});
Looks much nicer using lambdas:
使用 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);
});
}
});
Or just use RxBinding as stated by others.
或者只是像其他人所说的那样使用 RxBinding。
My solution above is a pretty general pattern for wrapping listeners into an Observable though.
我上面的解决方案是一个非常通用的模式,用于将侦听器包装到 Observable 中。
回答by user3783123
You can do this easily with Kotlin using extension functions. For example you write an extension function like this:
您可以使用扩展函数通过 Kotlin 轻松完成此操作。例如,您编写这样的扩展函数:
fun View.observableClickListener(): Observable<View> {
val publishSubject: PublishSubject<View> = PublishSubject.create()
this.setOnClickListener { v -> publishSubject.onNext(v) }
return publishSubject
}
And you would use this extension like this:
你会像这样使用这个扩展:
viewIWantToObserveClicks.observableClickListener().subscribe()