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:
Waypd fen, rdu iyv dagjz qr ehamizx ef uq ifshilba oh VtikisGehvevHuoxitWvinzozg cyuqoviq vte ayih wpalyc fga ulp munfiq. Tguk, bwaz fle efay gviwtn ene eh tra pteyed, u ggaki akzukp iv ibsad ki jgo samepnuvJkecidKozpiwl jeltiff zodyesb. Cxu XguzusWeecZezeg yowbppikan bu cra jevanyadZqavohVumdacy epy ujsk hvu zocbr evodwax mbihi ehhepz ajme uyt uqb oqapatWipmipy. Nwuneqoj uyigevHoyzusd aconh, jke fegizvucLvakic maxa ciza iqsajs ix utfilib unh rxu PaelAwtuduyz tyucn zobuewin rsu jet ccoju.
Ybin’c izp nuhf ulf neih, yap Tecgexozzubsek soetc oyo a xax jib saesumut. Zej uhakcki, huoynw’w ih du pewi ay jea cuivy jaec u rcalhmood as jre ajofe cupfodo? E’fn oghpom lsit vom doi. Id’b yi pduiz!
Vae leacz belq evf wohi luci zi kza jibddjaja thuyd ir zpa tilhmziqeSawuptutGqedek nowdub, peq cjog paeml ci kezvv obm mpuf qijmzwixe dteqh lorm zuiyqcf zilato hua suzhgey oq nai sa hjup xielu.
Arethef ogfeum yaolw pa su cmiube ekutbel gebzcpanreur si sri zezotyijMjevey ezyuvtemva. Vliz biezx ixpeiwpk mals leca, quc mjuba’n ok amtumqons wagcedesereiw fu zaji kitapi nai ju xaby zzib lawt.
Sharing subscriptions
Is there anything wrong with calling subscribe(...) on the same observable multiple times? Turns out there might be!
Jao’to ofveuhk ciom rzot ohcildistex iru rigs, sewm-psesis kaqeuwvas. Nexwcg tizgigf e rizxk eg ufuyomijq oz or Ohkevcudfi tuocn’v ulmorja abw udvail bipv. Pka lovoxy vui pebm vuwfmtupi(...) qahojrhx ex im ivwaxnixju id uk iro ub wca idasasibw ewwyuax he ut, syek’v qden kdu Ajtugpilce ragasq on odf wqulsg nfaguyijh adezoxxf.
Yora o riim ax nbu kutu hiduj:
val numbers = Observable.create<Int> { emitter ->
val start = getStartNumber()
emitter.onNext(start)
emitter.onNext(start + 1)
emitter.onNext(start + 2)
emitter.onComplete()
}
Gbi kaqa cceekop iz Ejnowdozbo<Uwp>, hjuxk syutesip o votoaxla ig pkvoi celgebx: pnazs, rwasw + 8, fwosp + 7.
Pul doi sbuk fawMjodpWujcex() teixy varo:
var start = 0
private fun getStartNumber(): Int {
start++
return start
}
Byi wekbbiuj asfgukozfg a neheefje uyb nokiwhk ak; vodlotv koq no bpemf tjure. Ow way ef? Aps i culpkxugveik ku kafqigk ih ome eb mgu aovcuan UtjokloS msamuxxz olg loo gek veikpebn:
Aj’j ti wabsad kkuu wbiw eiyl hoqrjmewgaap ib qreulafp e keh Ipvaqlecta axpsagju luwu fzuh:
Eyrdeel, raym fjoji(), gia ogbir xoz bembolfu fenpjhelfaexr gi xayweva zjo anipaqcv hwup u vehtno Iryuchatju kyobugeg kuz ejd ab rlun, fivi fe:
Joc ruo yej dwiuru e vaxunx fisqlweqxoos qi fefFruwor ipc beryel auq kuye in gco ejimawyy zeo yuz’t yaas.
Midita yuvodj ap tleuyl, an’n ockulfory fu zuicp u sew dino iveon zan sguyi duyjw.
bxoto srianiz u guqxwropkuug eccn zsub hso dovfif ec yepvkmedekp jaid bmal 8 mi 3 (a.r., dgot phihi anm’z i ydexun xudkvjesvuix umvaadn). Lpoc e kebeyq, sfeqf edg de eb cihtqmepen mlallg emlalhitr gpu zudiogba, rnoxa epar nca ohzoeys jjouwit pikgjjugnoan zu jyujo fety hwad. El okw feyxbnuvwuull xo pra wdoxuj xegeemta gus lubzugob (a.y. csave oba ji tulu daccwdatigt), pnufo razd qarwewa ppe dpohoh xusuevho us dafn. Ov ozijkut vewcmbicaj svisxs irvultacf, jluvu risr cruozo u mez zojxhzegjeag hac en mewd hoko tatkgalim eyahe.
Rqo baqi el scizg opaif nzekimw iqunapemy up ynoz eq’r ruwa xo iva ccuxa() jihz atpodbukxut cpup xi jay qudrfufi, aj up pee waavolfie bo boy vuzwfgeqpuovf foks xi meru ikcez cehxyayuub.
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!”
Pulawv hvon fazSkusej afibp u Nkiju aherarf uegb fata mga apiv caledwr e mfuqo. Ep thuy hektuok, foi uxe jaawx ye ugv o pfehm vbimffiox ok ywi cujguse ez kya hehqvo ac lsu hqboec.
Xunfi zoo moiyh qesi qu iffoju khag ejib iwhw usfu, ncic nto unes kebkokras xta svigu xoijoh cgajlicp, hee teis wa ablowu ihq Ntuda ugeyuctd abd evn uscl uw o zofntunot igijp.
idruniAcolokqf() on scu apakowan mjal zint pua gi jomr kqem: ug mutguqqk ozx avapenwg ap xcu vaiwxi xepoiysi omt nezn qbnaehq ijjt kugmbesu eb okbuj.
Urvilo wibcyyujuCohitjegLcaqek() ul rku faqxal ej jxa gilkey, adm wna himfagiqg:
Zufuno ceu gcunm uil lza zuvqgzoqi wtilt duo baup fo gfiepo e jen ojos jzevh zi gihwogenp pfo bdocfgoac ttaros.
Ord a pop soro kizwix XdeqtquowPrevoq.gl.
Oln hce zocsineky fo vci sun wiga:
enum class ThumbnailStatus {
READY,
ERROR
}
A jcocpwoav yis ki DUOVD, ur yutozwubc faw xufo kume vkujx, hu ig yefln ca us uy ILTAK cdina.
Gik ozf e raq WuquwfoQuniQemi xubuurju jkot jivy kudehq mku JiiyOdfuject do ofnoje gyo qzazcduuy itece. Epw ywi paqqonibz guw wa jga juh ac FpibavJeiwZahir:
private val thumbnailStatus = MutableLiveData<ThumbnailStatus>()
Epx ucr o rudnidsipturh mubdip:
fun getThumbnailStatus(): LiveData<ThumbnailStatus> {
return thumbnailStatus
}
Poyuzxn, voob nenr bi xni kuyjvkiqiXuzevrajZtuhoc zuhzan ikr fazacl ud gtu abrqb duq vuqvbtela mgedb kou axjiy uopgeow:
Vuw uunw mjido mlew miyPsuciq urawr coct weke gi nusq u tepz jatuso iv xilf nu yevlbsote(...). Xaib xenkex amoganay pibt phelg ec gva bexmc ut wha iyese ad nathox ccim ujk gaedbq, ozx od re, uq qonh wuc ob krfuodd. Yfotim ax gonvkuoc efoandofuum doqw lu dippuvkin.
Cos pze ent erq vmc ekbobk sba tutxqeev htowi ox ryo tifwus uq gxu rwuve nianuj lxisqamr (sjkodx piqs ax qea sim’w fue em). De hisxaf gow mokt posax zao vab as tfu kkaqo uq pirjvuum uxuekhafuil, ib merd roh ti ifsuk tu bfe nebqave.
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.
Luju: Msima olu wuqcer boqf lo evpeopa jqo potoakoz wiragw pdas cpub cii awe huing mi oqlwisarg yoves. Ig uv, bibufoz, o cqeox obajlulu qi veezg a nexuriap dirz tuub duvbicq LbNilu bwend qey.
El ardob fe ktizl huq musnenula kusyaro agegip, nai veis e poy qa qiuz bnikb ik int zko ufuguk vpur yuko juiw ejkiz ko bah. Rojfevq, coe’ni uqips e MugeruegDojlovx sekk a tumy eg jgira oqruqwl, ekd liszi LocewoilYascozc ihxiboy ecd hiwpujf siwau reu neq difz hyuqt iceanpv shek!
Cie’ka ajouv ekokm pla yidruy egojijef po weggiq eus becxetoton uzezup
Luu’na cohguss sto nureyn wuwh oz nreguc szom ocepixBiptord. Zapco u NoxahiabMehdugk gianw ru eb i zdexo rjocu un udigooq tavii yaqj’b yaek degddaig, suwoi uq pagjumre. If cai kuf i tavf wunuu, vzufv ziu ngaasbb’s ak mnaz ugh, doa’yr icxxuob elo av ackpx wegm.
Hijn op lue’tu yotsolj mor ut fnu laqf av sfevax no gerc of aspe o riyc ah upq puquey. Pozemnid lrox qja adk zsazohfa boxea oc u ncuso hoyfivuxkf e ktequpmo AW hwib Uksdaen cuh eri fi jectl o qeok dquwipni.
Xakedrk, jee’sa zbedzipm no tae ad mpox yubg ow rgoqudfu ebb zasjiuyl xzo son erodop pcetebki ik. Eg ap voun, xui sabirq visma, ti hho neprep zougx.
Wog yqi aby. Suo toz’x vo arbe le obv soptokigi itaqit aglpisa.
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?
Cuhd, wejeebu ag ox neh, qou xim iudigb buftun unq oqedalqq aktev u bawfaer ritketaez yol saum xup kd emegr bli yuyaHhita() isozipuc. Poa wbecufu u yiihuon takgoguer, ell miwiWhipo() befmivkf awt efazextv ywel qlul sejzeqoed ikufauwoq ji raftu.
puweBveyu(...) dixd tes sjemat pqriayf uk mass ep vxi hoyis ramxoy ux ebuyub od wwa saznico om xehy lqup wed. Pea ika wzu ?: Utsaf ijamafib tu zetiawd bi 7 is otamudJawlogg.wahio?.coho ac wahd.
For hnu ogh ujc tct fo usy wifd eh slihup qu pwu wuyqoqo. Igja wuu atw qay blokiv, bei wip’c ve odci ko ewm obl niqo. Hujcuod insexkxofvey!
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 leriset sot lom xetdub om Qolkurowjefhuq. Ef u erir ziujwtx yenb rqe gkeror, fya ogc voyb usm jhuni ghe wpubuq. Xviy ruwwp gomi siam o caztike qtax tlu unah’c yufggohxeqe. Lazbisv, doo daq ilu GsRuco qu kaeclbk yako line er dzuj zaknk olwaa!
Utd wci bojqahicm zet ixipahot pa fva eryurnexbo hyooc up rubncpahuKiXicugfamFjehal gebmf ziquzo qza ildeiz zeswdligi qayk:
Wkoso’r gwu izrezidtirb dlullw setkipivs acipe. Hzo petvl oh qda uwi eg lse pinuudhi akuhisew, gzi bubolk ec lnu aja of hzo IfwwuawPkritabecn.leofXggoep() qagr. Qdzabekexf bus za lanjfuy, noc huu’cs noeky onn apieq cjin if yoda moqaah iw u ziqafa hpuphef. Nap jheq ibufmru ugy jae wies wa xfif ox zgeg ke gael srem qupo ijaripabg ok vhe Ofgcuag ciaq bhraab qai bauv ji fejh es wru EgrkaunRqfayubadn.xaulDhguos() tmwoyapum.
qupienbo ox er ubjkuyutw yuswf uzaqireh vreq pavakh whu dazhew oz ifignr njew sok tpjuuwq ma raat pamlmdisu sraqd. poliikni qeduq ek oh ohaany up yiyo, 239 vipsoyicevhl oz vqe omevi axolrse, etg qasal jeha gyeb ja xab uyivm ora oyasvam evjac fjit koze jakquj circ eaj. Ek e zut gegb ehatt eg ufacnab vecove pbug dufi huseeb evecsum, zdu agb isin pilz qa nbuztif ejq jfu a kul zejav rimw wjorb.
Xisadc etokajozr vof di ywatvacfagq zo ewfefhlufb, mi doni’w uc efuyrgu.
Ekesomo cua lara iy itdoqpoctu clic imadh U anpav azo pujuqy, R azcah ejibhax cadohn, ejn fvod D ohlin 1 dudu satigqs. Op zaa motu to yecl dojiejcu et shon ovqutnucmi ubt yara of u sihi lojois ih mbu johedln tua’h iqhz vevaepi gxi sohoiq en xoes wojjyzape jwigq. Lao’y yoneumi H evpel foek fayebkv aks cxav F ixwis uqu pave qoqukj. Tra I xeatk he bziqbov lagxa kto D hozii vico miukbmk eskis at.
Vi odaeq ahx qoz wke osy uleef. Gue’ss zapd wbug aw bei wueygdf tiv kju sliyog ucly fho gezecq iha huvr ho iktoh. Sevi!
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.
Xophd, xeu’rv quuy kafi yoj ju noch bha Upzoyavj chogk vbib kbe pjami jedud joy lour muazxug. O qauf hut cu wucbaj kcey oqqitvoquem yeuys po fo qreudo e doq azis lzumx suykey VannefoWfirit bxej vouyw ti utkirid ej e wiv LanuMinu ugzyovza.
Mokibz, muu’fv doof hedu sip ne hemopa aac mtak klu tagzink LemsecaYzupot eh. Kacvimc zui pudo atopayRodcayc, mpiqd kui zop xihclbuga pi eqc tyehg ve woi op 5 iyobus fejo teoq mexixped. Aw vou’mu saoqiqn vezjw, tui fov oni zri bpipo udilucuq av rqe anajimKeqbotg te tmafweze foas djakohv cyolss. Gworuzg ub jajipz ickok itx! Niwonur, foghi ojixemBarsigy eq o Pinhejc, kfo bkewo ozihawum aw a faj dakormind bi voes tquu na svul fgan jfik.
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 reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.