ThrottleFirst巧妙使用
防止View被連續點擊,僅發送指定時間段內的第一個信號
RxView.clicks(btThrottleFirst)
.throttleFirst(3, TimeUnit.SECONDS)
.subscribe(new Action1<Void>() {
@Override
public void call(Void aVoid) {
Toast.makeText(mContext, "我是一個在3秒內不會被重複點擊的按鈕", Toast.LENGTH_SHORT).show();
}
});
PublishSubject
與普通的Subject不同,在訂閱時並不立即觸發訂閱事件,而是允許我們在任意時刻手動調用onNext(),onError(),onCompleted來觸發事件。
可以看到PublishSubject與普通的Subject最大的不同就是其可以先訂閱事件,然後在某一時刻手動調用方法來觸發事件,那麼拿他又能做些什麼?
舉個例子:當一個界面發生改變,通知另一個界面做出響應,以下是兩個Fragment之間通訊的Demo
1、首先在外部定義好公共的PublishSubject對象
PublishSubject<String> publishSubject = PublishSubject.create();
PublishSubjectTopFragment topFragment = new PublishSubjectTopFragment(publishSubject);
PublishSubjectBottomFragment bottom_Fragment = new PublishSubjectBottomFragment(publishSubject);
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fl_top,topFragment, "top")
.replace(R.id.fl_bottom, bottom_Fragment, "bottom")
.commit();
}
2、TopFragment中負責發出信息
@OnClick(R.id.btn_send)
void sendToBottom(){
String result = et_input.getText().toString().trim();
/**
*在這一時刻手動調用方法來觸發事件:
* 發出信息
*/
publishSubject.onNext(result);
}
3、BottomFragment中接收到通知後,產生響應
/**
* 這裏先訂閱事件:
* 接收到通知後,產生響應
*
*/
publishSubject.subscribe(new Action1<String>() {
@Override
public void call(String s) {
tv_result.setText("收到上級的祕密召令:"+s);
}
});
Buffer
buffer(count = 3):
Buffer操作符所要做的事情就是將數據安裝規定的大小做一下緩存,然後將緩存的數據作爲一個集合發射出去。
buffer(count = 2, skip = 3):
skip參數用來指定每次發射一個集合需要跳過幾個數據,指定的count爲2,skip爲3,就會每3個數據發射一個包含兩個數據的集合,如果count==skip的話,其就會等效於 buffer(count = 3) 了。
Scan
Scan操作符對一個序列的數據應用一個函數,並將這個函數的結果發射出去作爲下個數據應用這個函數時候的第一個參數使用,有點類似於遞歸操作
Observable.just(1,2,3,4,5)
.scan(new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer integer, Integer integer2) {
return integer*integer2;
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
tvResult.append(integer+"\n");
}
});
Distinct
Distinct操作符的用處就是用來去重,非常好理解,所有重複的數據都會被過濾掉。
Observable.just(1,2,3,1,1,2,1,4,5)
.distinct()
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
tvResult.append(integer+"");
}
});
而操作符DistinctUntilChanged則是用來過濾掉連續的重複數據。
Observable.just(1, 2, 3, 3, 3, 1, 2, 3, 3).distinctUntilChanged();
Filter
只會返回滿足過濾條件的數據
Observable.just(1,2,3,4,5)
.filter(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer>=3;
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
tvResult.append("被篩選過的戰鬥力大於等於3的大神們是:"+integer);
}
});
Skip、Take
Skip操作符將源Observable發射的數據過濾掉前n項
Take操作符則只取前n項,理解和使用起來都很容易,但是用處很大。另外還有
SkipLast和TakeLast操作符,分別是從後面進行過濾操作。
Observable.just("我","不","我","是","大","帥","鍋")
.skip(2)
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
tvResult.append(s);
}
});
Publish
什麼是Connectable Observable?
就是一種特殊的Observable對象,並不是Subscrib的時候就發射數據,而是隻有對其應用connect操作符的時候纔開始發射數據,所以可以用來更靈活的控制數據發射的時機。
而Publish操作符就是用來將一個普通的Observable對象轉化爲一
個Connectable Observable。需要注意的是如果發射數據已經開始
了再進行訂閱只能接收以後發射的數據
Connect
Connect操作符就是用來觸發Connectable Observable發射數據的。
應用Connect操作符後會返回一個Subscription對象,通過這個Subscription對象,我們可以調用其unsubscribe方法來終止數據的發射。
另外,如果還沒有訂閱者訂閱的時候就應用Connect操作符也是可以使其開始發射數據的。
使用
先使用publish操作符創建一個Connectable Observable:
private ConnectableObservable<Long> publishObserver() {
Observable<Long> obser = Observable.interval(1, TimeUnit.SECONDS);
obser.observeOn(Schedulers.newThread());
return obser.publish();
}
然後創建兩個Action1對象,在不同的時機對其進行訂閱:
ConnectableObservable<Long> obs = publishObserver();
Action1 action2 = o -> log("action2:" + o);
Action1 action1 = o -> {
log("action1:" + o);
if ((long) o == 3) obs.subscribe(action2);
};
obs.subscribe(action1);
mLButton.setText("start");
mLButton.setOnClickListener(e -> mSubscription = obs.connect());
mRButton.setText("stop");
mRButton.setOnClickListener(e -> {
if (mSubscription != null) {
mSubscription.unsubscribe();
}
});
當點擊start按鈕的時候對這個Connectable Observable 對象應用
connect操作符,讓其開始發射數據。
當發射到3的時候將action2給訂閱上,這個兩個訂閱者將同時收到相同的數據。點擊stop按鈕的時候終止其數據的發射。
RefCount
RefCount操作符就是將一個Connectable Observable 對象再重新轉化爲一個普通的Observable對象。
說點什麼吧
天啊,不知不覺,就完了啊。我的天,一個月啊,一個月前計劃的學習這些東西開始,到現在,居然到頭來發現,好像不是很多,又感覺挺滿足的了,好氣啊。
本身就喜歡去學習一些好玩的東西,所以,平時不是很忙的時候,都喜歡去默默踩一下坑,慢慢再填上去。
這些操作符主要太簡單,所以大部分的很多註釋和點我都註釋寫在了代碼裏面,Demo在這,有興趣的可以。。。。額,害羞的說一下,有興趣的可以來逛逛,萬一有啥合適的呢,緣分這種東西很難說的~~
https://github.com/GitHuborz/RxJavaOPDemo
月學習計劃總結
這一陣子,也是告一小段落了。
一個月前,準備了這個月的學習計劃,着手學習新知識,RxJava,Retrofit等等的這些。從剛開始聽着就覺得很屌的東西,從開始谷歌搜索資料,再慢慢一點點看下去,記下筆記和編寫Demo,感受這
些主流框架開源庫的強大和魅力之處,雖然現在做APP的機會不多,但有關這些的新科技還是時不時更新一下,學習多點,還是很棒的。
然後,這周主要是系統的學習了一番Rx 的我覺得實用的,也常有的操作符,學一個,寫一個Demo測試跟上,加上自己的理解,基本我覺得這些也就夠日常用了吧,至於不夠的,還可以自定義操作符呢,是吧。
O(∩_∩)O~
這段是時間的學習,也整理了一大部分筆記,準備整理一下,小更新一下C博客(RXJava(系列),好久都沒動了 ~都存在了雲筆記,沒辦法,懶。。
這次主要學習的內容,都有記錄下筆記,也都編寫對應的Demo,基本就這些了:
**1、MvpDemo (一個簡單的MVP架構的demo)
2、RetrofitRxJavaDemo (一個使用RxJava + Retrofit 的小demo)**
https://github.com/GitHuborz/MvpDemo-RetrofitRxJvaDemo
一個基於 RxJava+Retrofit+Mvp+… 的瀏覽Gank. 的妹子的學習小Demo
https://github.com/GitHuborz/MeiZi
RxJava 的所有常用操作符詳解+使用Demo
https://github.com/GitHuborz/RxJavaOPDemo
害羞(✿◡‿◡)~