如何从 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(() -&gt; 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 事件

如何绑定android点击事件

Android:如何在 ListView 的列表项中为 Button 设置 onClick 事件

如何在 Fragment 中捕获 onclick 事件