RxAndroid按钮单击Observer?

时间:2017-04-22 13:42:16

标签: android rx-android

嗨其他程序员,

按下按钮时,我使用RxAndroid每3秒进行一次间隔API调用。

private final CompositeDisposable disposables = new CompositeDisposable();

Observable fetchWeatherInterval = Observable.interval(3, TimeUnit.SECONDS)
        .map(new Function<Long, String>() {
            @Override
            public String apply(Long aLong) throws Exception {
                return getWeather("http://samples.openweathermap.org/data/2.5/weather?", "London,uk", "b1b15e88fa797225412429c1c50c122a1");
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());

Observer displayWeatherInterval = new Observer<String>() {

    @Override
    public void onError(Throwable e) {
        Log.e("Throwable ERROR", e.getMessage());
    }

    @Override
    public void onComplete() {
    }

    @Override
    public void onSubscribe(Disposable d) {
        disposables.add(d);
    }

    @Override
    public void onNext(String value) {
        textViewWeatherInterval.append(value);
    }
};

buttonFetchIntervalWeather.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            fetchWeatherInterval.subscribe(displayWeatherInterval);
        }
    });

我的问题是,是否有办法让按钮(或它的onClick监听器)成为一个Observable,并将其与其他按钮链接。

像buttonFetchIntervalWeather.subscribe(fetchWeatherInterval);

1 个答案:

答案 0 :(得分:9)

使用RxBinding

Subscription s = RxView.clicks(button)
        .throttleFirst(5, TimeUnit.SECONDS) // maybe you want to ignore multiple clicks
        .flatMap(foo -> fetchWeatherInterval)
        .subscribe(displayWeatherInterval);

throttleFirst只需停止接下来5秒的其他事件,因此如果用户多次点击该按钮,则会在接下来的5秒内再次触发相同的fetchWeatherInterval

flatMap将一个observable的输出转换为另一个observable,在这种情况下从click事件转换为fetchWeatherInterval。如果您需要更多信息,请阅读文档。

此外,RxJava2也可以,我刚刚为RxJava1回答了这个问题。只需将Subscription更改为Disposable。

使用Observable.create()

Observable.create(new Action1<Emitter<View>>() {
    @Override
    public void call(Emitter<View> emitter) {
        emitter.setCancellation(new Cancellable() {
            @Override
            public void cancel() throws Exception {
                button.setOnClickListener(null);
                emitter.onCompleted();
            }
        });
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                emitter.onNext(v);
            }
        });
    }
}, Emitter.BackpressureMode.DROP);

或者使用lambda:

Observable.create(emitter -> {
    emitter.setCancellation(() -> {
        button.setOnClickListener(null);
        emitter.onCompleted();
    });
    button.setOnClickListener(emitter::onNext);
}, Emitter.BackpressureMode.DROP);