如何从 OnClick 事件 Android 创建一个 Observable?
Posted
技术标签:
【中文标题】如何从 OnClick 事件 Android 创建一个 Observable?【英文标题】:How to create an Observable from OnClick Event Android? 【发布时间】:2014-10-16 22:34:27 【问题描述】:我是响应式编程的新手。所以我在从事件创建流时遇到问题,比如 onClick、ontouch...
谁能帮我解决这个问题。
谢谢。
【问题讨论】:
【参考方案1】:你会这样做:
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();
由于您使用的是 android,因此您可能已经包含了 contrib 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
);
编辑:从版本 1.x 开始,ViewObservable
and many helper classes are removed from RxAndroid。您将需要RxBinding library。
Observable<Void> buttonObservable = RxView.clicks(initiateButton);
buttonObservable.subscribe(new Action1<Void>()
@Override
public void call(Void x)
// do what you need here
);
【讨论】:
【参考方案2】:对于 Android 开发,请查看 Jake Wharton 的 RxBindings。例如,它允许你创建一个 observable 并订阅点击事件:
RxView.clicks(myButton)
.subscribe(new Action1<Void>()
@Override
public void call(Void aVoid)
/* do something */
);
或者,更好的是,使用 lambda 表达式(使用 Kotlin、Java 8 或 Retrolambda):
RxView.clicks(myButton)
.subscribe(aVoid -> /* do something */);
如果您使用的是 Kotlin,值得注意的是 RxBindings 还提供了Kotlin extension functions,允许您将每个绑定函数直接应用于目标类型。
【讨论】:
错误:-source 1.7 不支持 lambda 表达式【参考方案3】:您可以使用主题。
Subject 是一种桥接器或代理,既充当订阅者又充当 Observable。因为是Subscriber,所以可以订阅一个或多个Observable,又因为是Observable,所以可以通过remit的方式把它观察到的item传递过去,也可以发出新的item。
public class Events
public static PublishSubject <Object> myEvent = PublishSubject.create ();
当你想发布一些东西时
Events.myEvent.onNext(myObject);
当你想接收事件时
Events.myEvent.subscribe (...);
编辑
**使用架构组件 LiveData 更好,因为它处理活动或片段的生命周期,您不必担心取消订阅事件,因为它观察 ui 组件生命周期。
MutableLiveData<Object> event = new MutableLiveData<>();
当你想发布一些东西时
event.postValue(myObject);
当你想接收和事件时
event.observe(lifeCycleOwner, (myObject)->...);
【讨论】:
【参考方案4】:使用 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
);
);
使用 lambda 看起来更好:
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);
);
);
或者只是使用其他人所说的 RxBinding。
我上面的解决方案是一种非常通用的模式,用于将侦听器包装到 Observable 中。
【讨论】:
这里为什么要调用e.setCancellable()?我找不到文档。与 e.setDisposable() 相比有什么区别? @Gaket 要查看 Cancellable 和 Disposable 之间的区别,请查看此答案 ***.com/a/43283136/1502079 当我调用e.setCancellable(() -> view.setOnClickListener(null));
按钮对触摸做出两次反应,第二次触摸它调用e.setCancellable
内部的内容。为什么会发生这种情况?【参考方案5】:
您可以使用 Kotlin 使用扩展函数轻松完成此操作。例如你写一个这样的扩展函数:
fun View.observableClickListener(): Observable<View>
val publishSubject: PublishSubject<View> = PublishSubject.create()
this.setOnClickListener v -> publishSubject.onNext(v)
return publishSubject
你会像这样使用这个扩展:
viewIWantToObserveClicks.observableClickListener().subscribe()
【讨论】:
以上是关于如何从 OnClick 事件 Android 创建一个 Observable?的主要内容,如果未能解决你的问题,请参考以下文章
Android 如何在 Canvas 的 onDraw 方法中创建 onClick 事件
如何从 C++ 端连接到 QML 项目的 onClick 事件
如何在 Android 中为微调器捕获 onClick 事件