RxJava系列之combineLatest操作符及項(xiàng)目實(shí)際使用案例

(1)combineLatest基礎(chǔ)

RxJava的combineLatest()函數(shù)有點(diǎn)像zip()函數(shù)的特殊形式。

  • zip()作用于最近未打包的兩個(gè)Observables揖闸,其中一個(gè)Observable發(fā)射數(shù)據(jù)項(xiàng)后揍堕,組合所有Observable最早一個(gè)未被組合的數(shù)據(jù)項(xiàng)相反;

  • combineLatest()作用于最近發(fā)射的數(shù)據(jù)項(xiàng)汤纸,在其中一個(gè)Observable發(fā)射數(shù)據(jù)項(xiàng)后鹤啡,組合所有Observable所發(fā)射的最后一個(gè)數(shù)據(jù)項(xiàng)(前提是所有的Observable都至少發(fā)射過(guò)一個(gè)數(shù)據(jù)項(xiàng)),如下圖所示;

    combineLatest.png

    其原理即:如果Observable1發(fā)射了1,接著Observable2發(fā)射了A,combineLatest()將會(huì)處理1和A蹲嚣,組合成1A递瑰;而Observable1發(fā)射了2,此時(shí)Observable2只發(fā)射了A隙畜,所以combineLatest()將處理2和A抖部,組合成2A;待Observable2發(fā)射了B時(shí)议惰,此時(shí)Observable1發(fā)射的最后一個(gè)數(shù)據(jù)是2慎颗,combineLatest()將處理2和B,組合成2B言询;以此類(lèi)推組合成2C俯萎,2D,3D等等运杭。

(2)combineLatest項(xiàng)目實(shí)戰(zhàn)

  • EditText表單的校驗(yàn)
    這個(gè)示例中夫啊,包含用戶(hù)名、密碼輸入框辆憔,它們的長(zhǎng)度要求分別為2~8 和 4~16撇眯,如果兩者都正確报嵌,那么登錄按鈕的文案變?yōu)椤暗卿洝保駝t顯示“用戶(hù)名或密碼無(wú)效”熊榛。
public class CombineLatestActivity extends AppCompatActivity {
   private EditText mEtName;
   private EditText mEtPassword;
   private Button mBtLogin;
   private PublishSubject<String> mNameSubject;
   private PublishSubject<String> mPasswordSubject;
   private CompositeDisposable mCompositeDisposable;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_combine_latest);
       mEtName = (EditText) findViewById(R.id.et_name);
       mEtPassword = (EditText) findViewById(R.id.et_password);
       mBtLogin = (Button) findViewById(R.id.bt_login);
       //創(chuàng)建Subject
       mNameSubject = PublishSubject.create();
       mPasswordSubject = PublishSubject.create();
      //添加EditText輸入監(jiān)聽(tīng)
       mEtName.addTextChangedListener(new EditTextMonitor(mNameSubject));
       mEtPassword.addTextChangedListener(new EditTextMonitor(mPasswordSubject));
       //創(chuàng)建被觀(guān)察者
       Observable<Boolean> observable = Observable.combineLatest(mNameSubject, mPasswordSubject, new BiFunction<String, String, Boolean>() {
           @Override
           public Boolean apply(String name, String password) throws Exception {
               int nameLen = name.length();
               int passwordLen = password.length();
               return nameLen >= 2 && nameLen <= 8 && passwordLen >= 4 && passwordLen <= 16;
           }
       });
       //創(chuàng)建觀(guān)察者
       DisposableObserver<Boolean> disposable = new DisposableObserver<Boolean>() {
           @Override
           public void onNext(Boolean value) {
               mBtLogin.setText(value ? "登錄" : "用戶(hù)名或密碼無(wú)效");
           }
           @Override
           public void onError(Throwable e) {
           }
           @Override
           public void onComplete() {
           }
       };
       observable.subscribe(disposable);
       mCompositeDisposable = new CompositeDisposable();
       mCompositeDisposable.add(disposable);
   }
    private class EditTextMonitor implements TextWatcher {
        private PublishSubject<String> mPublishSubject;
        EditTextMonitor(PublishSubject<String> publishSubject) {
            mPublishSubject = publishSubject;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }

        @Override
        public void afterTextChanged(Editable s) {
            //發(fā)射數(shù)據(jù)
            mPublishSubject.onNext(s.toString());
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mCompositeDisposable.clear();
    }
}
  • 需求-對(duì)A對(duì)象上的某個(gè)List屬性進(jìn)行RxJava操作, 然后把操作的結(jié)果再重新賦給原來(lái)的A對(duì)象

比如返回一個(gè)用戶(hù)信息User, 里面有List屬性表示他的好友, 但好友的信息只有id, 需要再次通過(guò)id獲取好友具體信息

//獲取用戶(hù)信息
userApi.fetchUserInfo()
        .flatMap(new Func1<User, Observable<User>>() {
            @Override
            public Observable<User> call(User user) {
                printLog(tvLogs, "----fetch a user---- \n", getUserString(user))
                return fetchFriendsInfo(user);
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<User>() {
            @Override
            public void call(User user) {
                printLog(tvLogs, "----process his friends by id---- \n", getUserString(user));
            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                throwable.printStackTrace();
            }
        });

獲取好友信息并組合

//這個(gè)方法才是實(shí)現(xiàn)的核心
private Observable<User> fetchFriendsInfo(User user) {
    
    //保存User的數(shù)據(jù)
    Observable<User> observableUser = Observable.just(user);
    
    //對(duì)User的好友列表進(jìn)行單獨(dú)處理
    Observable<List<User>> observableUsers = Observable.from(user.getFriends())
            .flatMap(new Func1<User, Observable<User>>() {
                @Override
                public Observable<User> call(User user) {
                    //根據(jù)好友ID獲取更完整的信息
                    return userApi.fetchUserInfo(user.getId() + "");
                }
            })
            .toList();

    //對(duì)用戶(hù)User信息和他的好友信息進(jìn)行合并.
    return Observable.combineLatest(observableUser, observableUsers, new Func2<User, List<User>, User>() {
        @Override
        public User call(User user, List<User> users) {
            user.setFriends(users);
            return user;
        }
    });
}

上面大致的意思就是把User信息分為兩個(gè)部分:一部分是用戶(hù)信(Observable<User>), 一部分是好友列表(Observable<List<User>>)信息 锚国,然后把兩個(gè)最終數(shù)據(jù)進(jìn)行組合

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市玄坦,隨后出現(xiàn)的幾起案子血筑,更是在濱河造成了極大的恐慌,老刑警劉巖煎楣,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件豺总,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡转质,警方通過(guò)查閱死者的電腦和手機(jī)园欣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)休蟹,“玉大人沸枯,你說(shuō)我怎么就攤上這事÷腹” “怎么了绑榴?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)盈魁。 經(jīng)常有香客問(wèn)我翔怎,道長(zhǎng),這世上最難降的妖魔是什么杨耙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任赤套,我火速辦了婚禮,結(jié)果婚禮上珊膜,老公的妹妹穿的比我還像新娘容握。我一直安慰自己,他們只是感情好车柠,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布剔氏。 她就那樣靜靜地躺著,像睡著了一般竹祷。 火紅的嫁衣襯著肌膚如雪谈跛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天塑陵,我揣著相機(jī)與錄音感憾,去河邊找鬼。 笑死猿妈,一個(gè)胖子當(dāng)著我的面吹牛吹菱,可吹牛的內(nèi)容都是我干的巍虫。 我是一名探鬼主播彭则,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼鳍刷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了俯抖?” 一聲冷哼從身側(cè)響起输瓜,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芬萍,沒(méi)想到半個(gè)月后尤揣,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柬祠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年北戏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漫蛔。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嗜愈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出莽龟,到底是詐尸還是另有隱情蠕嫁,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布毯盈,位于F島的核電站剃毒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏搂赋。R本人自食惡果不足惜赘阀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脑奠。 院中可真熱鬧基公,春花似錦、人聲如沸捺信。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)迄靠。三九已至秒咨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掌挚,已是汗流浹背雨席。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吠式,地道東北人陡厘。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓抽米,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親糙置。 傳聞我的和親對(duì)象是個(gè)殘疾皇子云茸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • 一、RxJava操作符概述 RxJava中的操作符就是為了提供函數(shù)式的特性谤饭,函數(shù)式最大的好處就是使得數(shù)據(jù)處理簡(jiǎn)潔易...
    測(cè)天測(cè)地測(cè)空氣閱讀 626評(píng)論 0 1
  • 注:只包含標(biāo)準(zhǔn)包中的操作符标捺,用于個(gè)人學(xué)習(xí)及備忘參考博客:http://blog.csdn.net/maplejaw...
    小白要超神閱讀 2,184評(píng)論 2 8
  • 創(chuàng)建操作 用于創(chuàng)建Observable的操作符Create通過(guò)調(diào)用觀(guān)察者的方法從頭創(chuàng)建一個(gè)ObservableEm...
    rkua閱讀 1,802評(píng)論 0 1
  • 記錄RxJava操作符,方便查詢(xún)(2.2.2版本) 英文文檔地址:http://reactivex.io/docu...
    凌云飛魚(yú)閱讀 815評(píng)論 0 0
  • 這個(gè)頁(yè)面展示了創(chuàng)建Observable的各種方法揉抵。 **just(?)** — 將一個(gè)或多個(gè)對(duì)象轉(zhuǎn)換成發(fā)射這個(gè)或這...
    大于于閱讀 1,007評(píng)論 0 7