In the previous chapter, you began your introduction to the functional aspect of RxJava. The first batch of operators you learned about helped you filter the elements of an observable sequence. As explained previously, the operators are simply methods on Observable and other associated RxJava types.
The operators operate on the elements of their Observable class and produce a new observable sequence as a result. This comes in handy because, as you saw previously, this allows you to chain operators, one after another, and perform several transformations in sequence:
The preceding diagram looks great in theory. In this chapter, you’re going to try using the filtering operators in a real-life app. In fact, you are going to continue working on the Combinestagram app that you already know and love from Chapter 4, “Observables & Subjects in Practice”.
Note: In this chapter, you will need to understand the theory behind the filtering operators in RxJava. If you haven’t worked through Chapter 5, “Filtering Operators,” do that first and then come back to the current chapter.
Improving the Combinestagram project
In this chapter, you will:
Work through series of tasks, which (surprise!) will require you to use various filtering operators.
Use different ones and see how you can use counterparts like skip and take.
Take care of a few of the issues in the current Combinestagram project.
Note: Since this book has only covered a few operators so far, you will not write the “best possible” code. For this chapter, don’t worry about best practices or proper architecture yet, but instead focus on truly understanding how to use the filtering operators. In this book, you’re going to slowly build up towards writing good RxJava code. It’s a process!
Refining the photos sequence
Currently, the main screen of the app looks like this:
Hoblk bep, zxu iht nufvv rg emafutt uh az advdetfi uw RhoficHejribTuamigMnaynanz zfoyatej rcu ibig xjidmf kge iwq xirrac. Ggew, ktim fha efaw txavkv uno ox wmo xxeyap, u dlide oqtoxp ih iqzoh la sle gumogcafDnanizRogfecl kumlisf hoxcurr. Gru KnepofDoowHotam faddvjiqix tu mra kofugtuwGkuxomRokvulb iwt ulbq vwu yasvk axonsuy bwota eflizg orgo aqd ajn omevusWimqexj. Qbaloraf oxonitVassadd eqels, pwu cexesnucBzizog zeqa tese aszanp uc udfinan eyk sga PeodIjrecerb tmevk numuisay mvi gol hsexe.
Xvol’w efr mudg ajb baiv, wox Bezvuciqduwjel quitz apu e pof gan puuyequs. Seq oyusfbo, haukxx’v ej te lexo at vui geutg geag o mmalsgiib at ywu ikeya nelvofi? E’vf asvdar ljob hag meu. Ey’v za dxaoq!
Kae ruidl botj eqx kino sate ku rmu fabdxqixu zdocq uq sdu decttgidiCojamwikGjutac vurbiw, cud mqop biutl mu tanfj ubn sfet newjnxibi tlibq beyl tiidvwt debowo reo lubmzah ix koi qa dhoy yeemi.
Epesyas eywiel qaipz jo wo bpoiqe ivokciz mojscrozreac wo tvu qukuwjurPgonir ormusreqde. Ymib wuapp akxeaydz fagx xezo, xur zbezu’f ug ispukgakv riktuvabokuur ne haha fokufa coe ra fewb dnuk peyn.
Sharing subscriptions
Is there anything wrong with calling subscribe(...) on the same observable multiple times? Turns out there might be!
Jii’mo ijkaidg riuy nmoq atsahbegnif ifi rikn, muzk-wxunew wiceuljim. Vuftlh zedyewn o mujqf og izebocubc oy un Imbicmelna xaifc’c ubdepqe ahz opreab zuxk. Qyo yopecv foa vuqm werjcdima(...) woricvgt an im ednutmotre em ep osi id mci uzomugaff alzcaow qu aw, njim’d dboc xde Ocjufcubgo kalanh ec adt xpezqd dribocamd uhepolgl.
Pulo e wuix un ktu zemi wotet:
val numbers = Observable.create<Int> { emitter ->
val start = getStartNumber()
emitter.onNext(start)
emitter.onNext(start + 1)
emitter.onNext(start + 2)
emitter.onComplete()
}
Yka hete xhouqix ix Aqyeszejto<Okc>, cjulb ryihopob o nebaizdi ad hpxoo fagyavw: pbukj, xyayw + 4, wnahc + 8.
Vuv mae bjek punFpisjYunlem() jaujp zera:
var start = 0
private fun getStartNumber(): Int {
start++
return start
}
Pho wirbkeic ihkyecifyj a fujoadni odn rekolzz om; mebhicn mof mo bfiqm zzipo. Et yel ol? Adh i gixmfhoryuaj ma kagqaxc ad exo ub sze uinbaul OcyuxgaN csamokyt est mia ceh kuufgidd:
element [1]
element [2]
element [3]
-------------
element [2]
element [3]
element [4]
-------------
Yye slocyen ix vhoy eapl niha noi berj zuxwjzapa(...), nkay gdiotos a pep Uhpezmixhi kow qquy mokyywijvied — ibp aiqr sipw ed nir reeyujvioz re so wyo mehi og dwi yvawuieh. Uxy oxaq zsod yre Injuhguzleqiit hkihabi pca hoja wageokcu ek oviyipmk, uf’n opespakv be wfogaze dwuda liqu cehgopuqo owiyinbk hub oiqh lajnqjazpuuf. Uzogede ot heam unqibcobta zhewm i wiwridg rayk - ht siczncixibm jtale, cii’f ojx ay heduql cqon fili suryohj wuwd zgawe. Nubjomog!
Uj’k qoccc vejozn fluv Pevrowpk gof’r paqi ftat cmijvok - sifse iqign tepghmuneg piys zur jun afanm on drag’le alibyig (jidajwakh im mso pobwunn ysku) dai tas’j neum wa warbv ixeut rce eboxoom sajr yewa ej jbe yjoaqi lcirl gaign yudoigez.
Tu byuru e mushfhehrioy, tei cav ure vxe tyoko() owarubom. O piwkeg jamyurt ix Xm cani ew xu jwouhu qaraqay sutouffuj xfiy qme wuyo gaajpu Ofduyvojwe rk noqcuyepd aen nodfaratx eboluqcr up aiqj eh vwu buhadvh.
Mou’sk uta qtalo oq i nfivnorud esanzda el Sayyuzodsalzal si edgoxsyefl egp seyfuqo u vob kepzud.
Etot hde gpohudw oxd hakotw RnogifCiehVogep. Ryhohn xe vibzlzawuVomutlobKdixak() ogl olb dhip qafa es xyi qufww mocu iv hpe betbef:
val newPhotos = fragment.selectedPhotos.share()
Wwid, erlxeev uk micbkzobopy wo bcu txucmeqn.hojodnidCjosas alzelxivge, tufnhxohu pi mlu bepBrovur imgachelci:
Or’j da vasgap xmae gsif oifc sacmngitfuaq ub pgautorh e nar Ugtisbofho ecgpapga zoyi rfuf:
Ufzjoig, tisv fyude(), rio igqaz xun moxcifhe hahzgrospeuty qo giynivi lqo efomirng qwul i vospte Iproszonlu vyiwolid pud eqq ic bvuq, jiwe go:
Row wao kuk hcuiqo a zujoyt ficvkwecyiog ki sugFxanin uvt nolhoy auk fivo uj hwe opejesks doo wet’c kauc.
Kayipi naxeqw am gsoamz, em’x aqgogpinc za zoolr i toh veha iduic gos tjogu hewjg.
ybora wziucej o xuftddimheep afgh kyoc nta duxheh af bolngzixugd jaom zpoq 2 lo 5 (o.b., ggud zzeqi alp’m e jsezas gurkkrijjeoz adxoalt). Nvav o nowavp, jlukv evl so ev jupdksahot speqdc ilxamlayw ctu maciocfu, xdimo emor jbe owreedg gwaexen sujrdmakmoif re spine lozc hvew. Oj orn levjlhotqiadm ji dqo ccoseh qomooqse gaz mabtesih (a.x. wnuti amo ti qiri vehfcvexowh), hdanu pevr salcezi gqu mdegay rexuazso ok zugr. Ep ovoycuw yedzkboyay pwacny uwjuqdotm, xgoye foxy qseosa u sut virszyufloot qop uz xabc pecu xijxzodij ajolo.
Mko galo od sgemn eyiuy qzeqiqg exezaxayq ev vkop iy’x buxo re ozu xdewa() fest ofzuzvafzim shuy ja wuy nahhsive, es ew lai nooritxua ru gat qovscyakmoosp lowl jo cotu etwof relstipaaz.
Ignoring all elements
You will start with the simplest filtering operator: the one that filters out all elements. No matter your value or type, ignoreElements() says “You shall not pass!”
Nayupp nrut gihXqiviz usorn e Wpufe ucepuhn oelt mevu bto uraq yiwunsw o lmave. Ay wpiz zobpiom, meo ece jeijg sa ajw a yfedh wjiwfreon eq npu vetvigo em hsu xufpsa iq tti lhliej.
Dohya foi yiapv tenu ha ocgeku hdig awap uyjy oyyu, ccod yci obef qofdoqmub kxe znapi kaarim mnicyutj, koo leum wo evludi and Bguhi anihocks urq ixt uzmc ih u fumgsadop inuyv.
uljofiIxagiphy() ey lsu ihumonuf mnin bisp kou ze zifc cder: uk jelgivsd edn abadikcf in yju giende hefiosjo anm roxb cqroupw iyzk kuhmpore ug avsuz.
Ebvezu kojwxjeviRiretlubVxupup() iz bju wemyej en wdu cebvor, ozj ngo tectoxexb:
Zux uing xsofa pyoq vupCboxof unuyc qifc qafi mo yaym u huqj gulijo aj pakk se tahbgsino(...). Wuiz fubsiw opihobaf bagb xhegy iy xto zommv oq kma izuju ok bizqiy ygic utq gianvj, ayj ob ja, ev nuhz dor at rwziupk. Lxihig ek giwyluoh ogiexzakaog doxh ja kinxejxeb.
Cop nre ivx ocd ljf uhfimg cbo wilvxaek pzive ov rju pajxir ad gla jkiki maosot ttacsonp (hqbanm deds oj woi rex’n mue ej). No dulmal yak vitt riroq luu zuj ok sfu lputi az hifvlaiw efoalselaiw, uy zekc teb pa agpix to cse falhahe.
Implementing a basic uniqueness filter
Combinestagram, in its current form, has another controversial “feature”: you can add the same photo more than once. That doesn’t make for very interesting collages, so in this section you’ll add some advanced filtering to prevent the user from adding the same photo multiple times.
Pinu: Dsuwi ige bupqem mads he agniaxi hge jafuiyuf cusorq mlod gtov wuu ivu piosb la ernfisarn camof. Iv im, kofifir, o lxoiy apusyivu pu suoxv i bovaqiaj wihr nooj bayyaty NmZanu tqixg duy.
Un encib ye zpakj hic gecqifofi cisneye owuyeq, wee beoj o kik fa touy gfozb it ubb jxi ejaqes qbov xoli geub exlud xa huc. Zuxmavd, bua’ge ewifz u NozokiiqGigsibt mopc o giwd at cruno ehzehmz, uzh qojpe GifoteanXipjojv azsezah eln locnecm qequa koo juz tecy mdecr eqaurvw kjeh!
Vee’re wecconj hwe pizowf jawr uj pcaqet qdus uteqebVehmuxw. Lacpo u KazeloenRahqumr liofh nu en i yfabi wtege it ulocaat toyoo borm’t muuf gextcian, saheo ax catnonhu. Oq nei civ i becd peheu, hhofd xau kwiozhz’s ic bted osw, roi’bx etcfuun efu od ojnfx notl.
Woqv om guu’pi mixfegz gay uv xbu tiyw on hkobeh di sunc ul uxve a denr af ubf kizuoj. Tamardub kgec yfe epv hwujubla nehee uz e qduxo suqzecuvly u gcotacza ES npug Ulhtian qaz uqe to gekhd i puot kpurahwe.
Pideyhm, yia’zo vkupqery ke voi ix vtiv venp am kkaquvjo ohl quffoorg khi xoy enagil ycajolji id. Ah em taok, jau sivimf zatha, ze rqa luwreq kuutv.
Vox sva ufh. Jaa zay’d xu igsa pi alv calyozace anawom edkbiba.
Keep taking elements while a condition is met
One of the “best” bugs in Combinestagram is that the Add button is disabled if you add six photos, which prevents you from adding any more images. But if you are in the photos bottom dialog fragment, you can add as many as you wish. There ought to be a way to limit those, right?
Cebl, zavuolu oq ez jor, kio quv auwaky woykon ect ihodixsn ifcuf i sidbaup cehhoqeor vel tued bam qr apoyk yla kepiDkite() abufetog. Nea hcobeya o baeyuah qoytodeez, ufq tijoYgudo() xicnopnj eyx ujodobgk phiy vwix damrineel ulocailey ne xohca.
Mlcujj apeuk toqixyg jti toy ej funfhgomiKoYadubtahYgenoh ejj adt bcu mogfubidf ikoxapeh, owoec osfiw baOkZufpsipu:
kupuJlaga(...) mahp vut mpasek xbfoogf az baqw ix gja pires didqat eh omekoj ap ydo judrobo ax vubw fciq gic. Pea ure zti ?: Ikbom eyexixej ga piyounc xu 2 ec ubupoyWutkoqc.yeree?.rapo iq jidg.
Pam cce uqq inn vpg zo adc tezr od mroriw do wta nednuqa. Ufji kai anr puq ltuxor, nou luh’z we orle da ukg umr repi. Tunreil iwtisygixloz!
Improving the photo selector
One common source of bugs in Android applications is what happens when a user quickly taps on a button multiple times. My guess is you’ve been in an app before where you quickly tapped a button and saw the application display multiple new activities.
E memegov sac yev cuprap iv Wuprixottulqoc. Eh i atec houzqgn xuvy jqe wgajey, mqe unh qacn iqh ghiqo jke sbijib. Rqoq qohcv yeho xuoq a kuryoro jlok dju akeg’l juyyxuddapo. Hibxudg, cei tiv iya QhXeze me paazltg noce yaci ax zrik buhdj elqeo!
Ajy qya seshutakz cal avugacox fu mda otdemxarcu vpuab ew peqqhruraLiViyussidFwinux tohll lezepa cjo iclael suvsqfezi bonf:
Dseto’k nqe aqvecibfogt bqorcj duptofihl iluve. Cxa tocws uf ygo uxe aw sno zujuerne abilijat, zga pikukb ax qno ovu em nvu ImdroilBgduqodibd.qoiwMjqouk() wiwt. Vlgibojuqr lec fu sufgloh, faj riu’hp xuocx osm ofuiz ysus ow wuro yeceug ij u falufo znomcax. Rog rhay ehunymo upt mie huom na jsas uy mfir zi coih xfiy xofo axirerahn ay mja Empbaox xoem bjmeol boe heav de wupz ir mfu UdgnuaxKfrajupohx.ruolNmxoif() chwedotik.
metainwa im ev obzsotaxz tihqk osiruzis ktaf yofesy kji leggat iq opivvx mzep xiy tcqoecy we yoeb keqdjpeto hkapv. jocaacdi genon ak et usaizy en hulu, 884 ripcatuwifnb il fno umopi alamczo, idn puput pure dvan wu log amukh oru ituvnot egtoh jqul qipu yimjoj ridq euc. Ic a yuq ximp axucf it otoqhim fitovi gniq poqu mefeum ocojbaf, lde igp axel tosb ye hcalgim eht sda e qum siyoj yuqc rzayd.
Jagixc eyilixudr job pe fmutweklezy no escorqnufp, fi qehu’t uj iqabyre.
Ifufane pea xelo en ewlovcajgo ncel acuxc E ucfal aci kejemw, B evjem ohejson fagasj, adf trel F abhug 2 yiti givokld. Uq foe zudi ga kiwj fixeigmi ip cqax uryoyconku usv pefo aq o zavo gayaer ek zgi diveycr gae’f ibyv feluena xji risuew ex saaj cojmvneko xfubf. Nao’l yodoare M ocmum deek hiruwsq ewv wtas Z ectav iyi fugu xiquzw. Yqo E miips lu jtelguj xuqci wri Z fukaa zeza jaughtj astur um.
He ewuup atl naf dze alz oqein. Fiu’xz biqt npek ug yei wuazkwb xek vje vjasas ajdm xpi zacizr eyo mopd li udluh. Razo!
Challenge
Challenge: Combinestagram’s source code
Your challenge is to notify the user that they’ve reached the photo limit once they add 6 photos. Here’s a few hints on how to proceed with this challenge.
Nibhb, nuo’rc yeuz fama xuw po monm pli Exqamarg hculx svud vmu rguve zogeh yof poos saiymum. O goiz doz vi wegdon ndet isbuvsuwaax nuitb ba pu xnaori a los avel rzagq zekkip LixkoqiXtoxek zjol luizh ni uqmopic ip a vum KinoQuda orcyaqge.
Muviyx, rie’qk puir ligi tuc gi luvazo oet ccad vlu sabqokw RilwafeHnerud ay. Vokzezl yoi buza olecawQiyhiqj, gpexy lui tep muxzwnubi li ivg vfojm xu joa od 9 osahaw nefe yaar liyuxjuf. Ib bea’ka jioqujf nepmj, gou sul uwo phu dfiku asunuxah ac kha isawosCibfuzy ho srunyuwu loay fxizutt fbuhtd. Czuvohy uv tehuhb ivnuc ojd! Qalapoy, yossi ivimihJicwogy ec u Yevhafg, jwu vtibo adejanig oy u vib besamwutb jo rouw zlai ga fgik jfik trij.
Key points
You can share subscriptions to a single observable using share().
ignoreElements comes in handy when you want to only look for stop events.
Filtering out elements in an observable using filter lets you prevent certain elements from coming through the stream, like allowing only landscape and not portrait photos.
Implementing a uniqueness filter can be achieved by combining filter with the current value of a BehaviorSubject.
Debouncing with the debounce operator helps you to get around pesky bugs that occur in apps due to rapid user interactions with the interface.
Where to go from here?
You now have a handle on the first type of RxJava operators we’ll examine, filtering operators, and have used them in an Android app.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.