Подтвердить что ты не робот

Как создать Observable из OnClick Event Android?

Я новичок в реактивном программировании. Поэтому у меня возникает проблема при создании потока из события, например onClick, ontouch...

Может ли кто-нибудь помочь мне решить эту проблему.

Спасибо.

4b9b3361

Ответ 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 и многие вспомогательные классы удалены из RxAndroid. Вам потребуется библиотека RxBinding.

Observable<Void> buttonObservable = RxView.clicks(initiateButton);
    buttonObservable.subscribe(new Action1<Void>() {
        @Override
        public void call(Void x) {
            // do what you need here
        }
    });

Ответ 2

Для разработки Android взгляните на Джейк Уортон RxBindings. Например, он позволяет создавать заметки и подписываться на события кликов с помощью:

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

или, что еще лучше, с лямбда-выражениями (используя Kotlin, Java 8 или Retrolambda):

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

Если вы используете Kotlin, стоит отметить, что RxBindings также предоставляет функции расширения Kotlin, которые позволяют применять каждую функцию привязки непосредственно к целевому типу.

Ответ 3

Вы можете использовать тему.

Субъект - это своего рода мост или прокси, который действует как подписчик и как наблюдаемый. Поскольку он является подписчиком, он может подписаться на одну или несколько наблюдаемых, а поскольку он является наблюдаемым, он может проходить через элементы, которые он наблюдает, переиздавая их, и он также может излучать новые элементы.

public class Events {
    public static PublishSubject <Object> myEvent = PublishSubject.create ();
}

Когда вы хотите опубликовать что-то

Events.myEvent.onNext(myObject);

Когда вы хотите получить событие

Events.myEvent.subscribe (...);

редактировать

** Использование компонентов архитектуры LiveData лучше, потому что он обрабатывает жизненный цикл и активность или фрагмент, и вам не нужно беспокоиться об отказе от подписки на события, потому что он наблюдает жизненный цикл компонентов пользовательского интерфейса.

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

Выглядит намного лучше, используя 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.

Ответ 5

Вы можете сделать это легко с Kotlin, используя функции расширения. Например, вы пишете функцию расширения следующим образом:

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

И вы бы использовали это расширение следующим образом:

viewIWantToObserveClicks.observableClickListener().subscribe()