如何从OnClick事件Android创建一个Observable?

时间:2014-08-23 01:53:42

标签: android reactive-programming rx-java

我是反应式编程的新手。所以我在从事件创建流时遇到问题,比如onClick,ontouch ......

任何人都可以帮我解决这个问题。

感谢。

5 个答案:

答案 0 :(得分:51)

你会做这样的事情:

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,因此您可能已经包含了现在称为rxjava-android的contrib 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
        }
    });

答案 1 :(得分:26)

对于Android开发,请查看Jake Wharton的RxBindings。例如,它允许您创建一个observable并订阅点击事件:

RxView.clicks(myButton)
        .subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {
                /* do something */
            }
        });

或者更好的是,使用lambda表达式(使用KotlinJava 8Retrolambda):

RxView.clicks(myButton)
        .subscribe(aVoid -> /* do something */);

如果你正在使用Kotlin,那么值得注意的是RxBindings还提供Kotlin extension functions,允许你直接在目标类型上应用每个绑定函数。

答案 2 :(得分:16)

您可以使用主题。

Subject是一种桥接器或代理,既可作为订阅者也可作为Observable。因为它是一个订阅者,它可以订阅一个或多个Observable,并且因为它是一个Observable,它可以通过重新发送它来传递它所观察的项目,并且它也可以发出新项目。

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)->...);

答案 3 :(得分:13)

使用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
            }
        });
    }
});

使用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);
        });
    }
});

或者只是按照其他人的说法使用RxBinding。

上面的解决方案是一个非常通用的模式,用于将侦听器包装到Observable中。

答案 4 :(得分:0)

您可以使用Kotlin的扩展功能轻松地做到这一点。例如,您编写了这样的扩展功能:

    fun View.observableClickListener(): Observable<View> {
    val publishSubject: PublishSubject<View> = PublishSubject.create()
    this.setOnClickListener { v -> publishSubject.onNext(v) }
    return publishSubject
}

您将使用以下扩展名:

viewIWantToObserveClicks.observableClickListener().subscribe()