2017-04-22 96 views
0

嗨同行程序員,RxAndroid按鈕點擊觀察者?

我正在使用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監聽器)可觀察到過,並與其他IT連鎖。

類似buttonFetchIntervalWeather.subscribe(fetchWeatherInterval);

回答

2

使用RxBinding

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

throttleFirst只是停止進一步事件5秒左右,所以如果用戶多次點擊按鈕,同樣fetchWeatherInterval不會被再次觸發,在接下來的5秒,當然。

flatMap將一個observable的輸出轉換爲另一個observable,在這種情況下,從click事件轉換爲fetchWeatherInterval。如果您需要更多信息,請閱讀文檔。

另外,RxJava2的工作原理,我只是回答了RxJava1。只需將訂閱更改爲一次性。

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

或者與拉姆達:

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

我會嘗試一下,回來給你。我想問一下使用這個lib是否會有問題,因爲我使用Rx 2.0,它沒有Subscription並且有CompositeDisposable,如果你能解釋爲什麼我需要flatMap(可能是throttleFirst()?),你的意思是說也許使用Observable.create()。謝謝你的回答,時間很親切。 –

+0

編輯我的答案 – Sourabh

+0

這個答案是完美的,寫得很好。它幫了很多,謝謝。 –