package Ġcom . d ania . product finder . ui . search Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . os . IB inder Ċ import Ġandroid . view . KeyEvent Ċ import Ġandroid . view . LayoutInflater Ċ import Ġandroid . view . View Ċ import Ġandroid . view . ViewGroup Ċ import Ġandroid . view . input method . Editor Info Ċ import Ġandroid . view . input method . Input Method Manager Ċ import Ġandroidx . core . view . is G one Ċ import Ġandroidx . databinding . Data Binding Component Ċ import Ġandroidx . databinding . Data Binding Util Ċ import Ġandroidx . fragment . app . Fragment Ċ import Ġandroidx . fragment . app . view Models Ċ import Ġandroidx . lifecycle . Observer Ċ import Ġandroidx . lifecycle . ViewModel Provider Ċ import Ġandroidx . recyclerview . widget . Linear LayoutManager Ċ import Ġandroidx . recyclerview . widget . RecyclerView Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . Global Scope Ċ import Ġkotlinx . coroutines . launch Ċ import Ġtim ber . log . Tim ber Ċ import Ġjavax . inject . Inject Ċ import Ġcom . d ania . product finder . App Executors Ċ import Ġcom . d ania . product finder . R Ċ import Ġcom . d ania . product finder . binding . Fragment Data Binding Component Ċ import Ġcom . d ania . product finder . databinding . Search Fragment Binding Ċ import Ġcom . d ania . product finder . di . Injectable Ċ import Ġcom . d ania . product finder . ui . common . Product ListAdapter Ċ import Ġcom . d ania . product finder . ui . common . Retry Callback Ċ import Ġcom . d ania . product finder . ui . common . Record ListAdapter Ċ import Ġcom . d ania . product finder . ui . common . Task Listener Ċ import Ġcom . d ania . product finder . util . auto Cle ared Ċ Ċ /** Ċ Ġ* ĠA Ġsimple Ġ[ Fragment ] Ġsubclass . Ċ Ġ* ĠUse Ġthe Ġ[ search _ fragment . newInstance ] Ġfactory Ġmethod Ġto Ċ Ġ* Ġcreate Ġan Ġinstance Ġof Ġthis Ġfragment . Ċ Ġ*/ Ċ class ĠSearch Fragment Ġ: ĠFragment (), ĠInjectable Ġ{ ĊĊĠĠĠ Ġ@ Inject ĊĠĠĠ Ġlateinit Ġvar ĠviewModel Factory : ĠViewModel Provider . Factory ĊĊĠĠĠ Ġ@ Inject ĊĠĠĠ Ġlateinit Ġvar Ġapp Executors : ĠApp Executors ĊĊĠĠĠ Ġvar Ġdata Binding Component : ĠData Binding Component Ġ= ĠFragment Data Binding Component ( this ) ĊĊĠĠĠ Ġvar Ġbinding Ġby Ġauto Cle ared < Search Fragment Binding >() ĊĊĠĠĠ Ġvar Ġadapter Ġby Ġauto Cle ared < Product ListAdapter >() ĊĠĠĠ Ġvar Ġrecord Adapter Ġby Ġauto Cle ared < Record ListAdapter >() ĊĊĠĠĠ Ġval Ġsearch ViewModel : ĠSearch ViewModel Ġby Ġview Models Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Factory ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate View ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinflater : ĠLayoutInflater , Ġcontainer : ĠViewGroup ?, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠsavedInstanceState : ĠBundle ? ĊĠĠĠ Ġ): ĠView ? Ġ{ ĊĠĠĠĠĠĠĠ Ġbinding Ġ= ĠData Binding Util . inflate ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinflater , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . layout . search _ fragment , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontainer , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata Binding Component ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġbinding . root ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon View Created ( view : ĠView , ĠsavedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġbinding . lifecycle Owner Ġ= Ġview Lifecycle Owner ĊĠĠĠĠĠĠĠ Ġinit RecyclerView () ĊĠĠĠĠĠĠĠ Ġinit RecyclerView Suggest () ĊĠĠĠĠĠĠĠ Ġval Ġrv Adapter Ġ= ĠProduct ListAdapter ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata Binding Component Ġ= Ġdata Binding Component , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapp Executors Ġ= Ġapp Executors , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow FullName Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ) Ġ{ Ġrepo Ġ-> ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbinding . query Ġ= Ġsearch ViewModel . query ĊĠĠĠĠĠĠĠ Ġbinding . product List . adapter Ġ= Ġrv Adapter ĊĠĠĠĠĠĠĠ Ġadapter Ġ= Ġrv Adapter ĊĊĠĠĠĠĠĠĠ Ġval Ġrv Record Adapter Ġ= ĠRecord ListAdapter ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata Binding Component Ġ= Ġdata Binding Component , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapp Executors Ġ= Ġapp Executors , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow FullName Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtask Listener Ġ= Ġobject Ġ: ĠTask Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Task Click ( task : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Search Ġs lect ed Ġ${ task }"); ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . delete All Button . is G one Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . search EditText . setText ( task ); ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsearch ViewModel . set Query ( task ); ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdismiss Keyboard ( view . window Token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelete Listener Ġ= Ġobject Ġ: ĠTask Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Task Click ( task : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Delete Ġs lect ed Ġ${ task }"); ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠGlobal Scope . launch ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsearch ViewModel . delete Items . delete Item ( task ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġbinding . back Arrow . setOnClickListener { ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . count Product TextView . is G one Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . record List . is G one Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . product List . is G one Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . delete All Button . is G one Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . back Arrow . is G one Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . search EditText . setText ("") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġbinding . record List . adapter Ġ= Ġrv Record Adapter ĊĠĠĠĠĠĠĠ Ġbinding . count Product TextView . text Ġ= Ġ" Products " ĊĠĠĠĠĠĠĠ Ġrecord Adapter Ġ= Ġrv Record Adapter ĊĊĠĠĠĠĠĠĠ Ġinit Search Input Listener () ĊĊĠĠĠĠĠĠĠ Ġbinding . callback Ġ= Ġobject Ġ: ĠRetry Callback Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġretry () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsearch ViewModel . refresh () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġbinding . delete All Button . setOnClickListener { ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠGlobal Scope . launch ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsearch ViewModel . delete Items . delete All Items (); ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinit Search Input Listener () Ġ{ ĊĠĠĠĠĠĠĠ Ġbinding . search EditText . setOn Editor ActionListener Ġ{ Ġview : ĠView , Ġaction Id : ĠInt , Ġ_: ĠKeyEvent ? Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( action Id Ġ== ĠEditor Info . IME _ ACTION _ SEARCH ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdo Search ( view ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbinding . search EditText . setOn Key Listener Ġ{ Ġview : ĠView , ĠkeyCode : ĠInt , Ġevent : ĠKeyEvent Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( event . action Ġ== ĠKeyEvent . ACTION _ DOWN Ġ&& ĠkeyCode Ġ== ĠKeyEvent . KEYCODE _ ENTER ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdo Search ( view ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdo Search ( v : ĠView ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġquery Ġ= Ġbinding . search EditText . text . toString () ĊĠĠĠĠĠĠĠ Ġ// ĠDis miss Ġkeyboard ĊĠĠĠĠĠĠĠ Ġdismiss Keyboard ( v . window Token ) ĊĊĠĠĠĠĠĠĠ Ġval ĠisEmpty Query Ġ= Ġquery . isEmpty () ĊĠĠĠĠĠĠĠ Ġbinding . count Product TextView . is G one Ġ= ĠisEmpty Query ĊĠĠĠĠĠĠĠ Ġbinding . record List . is G one Ġ= Ġ! isEmpty Query ĊĠĠĠĠĠĠĠ Ġbinding . product List . is G one Ġ Ġ= ĠisEmpty Query ĊĠĠĠĠĠĠĠ Ġbinding . delete All Button . is G one Ġ= Ġ! isEmpty Query ĊĠĠĠĠĠĠĠ Ġbinding . back Arrow . is G one Ġ= Ġ! isEmpty Query ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! query . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsearch ViewModel . set Query ( query ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinit RecyclerView () Ġ{ ĊĊĠĠĠĠĠĠĠ Ġbinding . product List . add On Scroll Listener ( object Ġ: ĠRecyclerView . On Scroll Listener () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Sc rolled ( re cyclerView : ĠRecyclerView , Ġdx : ĠInt , Ġdy : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlayout Manager Ġ= Ġre cyclerView . layout Manager Ġas ĠLinearLayoutManager ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Position Ġ= Ġlayout Manager . find Last Visible Item Position () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( last Position Ġ== Ġadapter . item Count Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsearch ViewModel . load Next Page () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġbinding . search Result Ġ= Ġsearch ViewModel . results ĊĠĠĠĠĠĠĠ Ġsearch ViewModel . results . observe ( view Lifecycle Owner , ĠObserver Ġ{ Ġresult Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . record List . is G one Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . product List . is G one Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . back Arrow . is G one Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadapter . submit List ( result ?. data ) ĊĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠ Ġsearch ViewModel . load More Status . observe ( view Lifecycle Owner , ĠObserver Ġ{ Ġloading More Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( loading More Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . loading More Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . loading More Ġ= Ġloading More . isRunning ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġerror Ġ= Ġloading More . errorMessage IfNot Handled ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinit RecyclerView Suggest () Ġ{ ĊĊĠĠĠĠĠĠĠ Ġsearch ViewModel . list Suggest . observe ( view Lifecycle Owner , ĠObserver Ġ{ Ġresult Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result . isEmpty ()){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . delete All Button . is G one Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( binding . search EditText . text . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . delete All Button . is G one Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġrecord Adapter . submit List ( result ) ĊĊĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġdismiss Keyboard ( window Token : ĠI Binder ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġimm Ġ= Ġactivity ?. getSystem Service ( Context . INPUT _ METHOD _ SERVICE ) Ġas ĠInput Method Manager ĊĠĠĠĠĠĠĠ Ġimm . hide Soft Input From Window ( window Token , Ġ 0 ) ĊĠĠĠ Ġ} Ċ } Ċ