package Ġcom . si lo finance . si lo . expense čĊč Ċ import Ġandroid . app . DatePicker Dialog č Ċ import Ġandroid . os . Bundle č Ċ import Ġandroid . text . Input Filter č Ċ import Ġandroid . view . LayoutInflater č Ċ import Ġandroid . view . View č Ċ import Ġandroid . view . ViewGroup č Ċ import Ġandroid . widget . Toast č Ċ import Ġandroidx . databinding . Data Binding Util č Ċ import Ġandroidx . fragment . app . Fragment č Ċ import Ġandroidx . lifecycle . ViewModel Provider č Ċ import Ġandroidx . navigation . fragment . find Nav Controller č Ċ import Ġandroidx . preference . Preference Manager č Ċ import Ġandroidx . recyclerview . widget . Grid LayoutManager č Ċ import Ġcom . si lo finance . si lo . Decimal Digits Input Filter č Ċ import Ġcom . si lo finance . si lo . R č Ċ import Ġcom . si lo finance . si lo . adapter sand utils . Account Emoji Adapter č Ċ import Ġcom . si lo finance . si lo . adapter sand utils . Category Emoji Adapter č Ċ import Ġcom . si lo finance . si lo . databinding . Fragment Expense Binding č Ċ import Ġcom . si lo finance . si lo . db .* č Ċ import Ġcom . si lo finance . si lo . hide Keyboard č Ċ import Ġjava . text . SimpleDateFormat č Ċ import Ġjava . time . LocalDateTime č Ċ import Ġjava . time . Zone Id č Ċ import Ġjava . util .* čĊčĊč Ċ class ĠExp ense Fragment Ġ: ĠFragment () Ġ{ čĊčĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġbinding : ĠFragment Expense Binding čĊĠĠĠ Ġprivate Ġlateinit Ġvar ĠviewModel : ĠExp ense ViewModel čĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġcal : ĠCalendar čĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġactive Accounts List : ĠList < Account > čĊčĊčĊĠĠĠ Ġoverride Ġfun ĠonCreate View ( in flater : ĠLayoutInflater , Ġcontainer : ĠViewGroup ?, ĠsavedInstanceState : ĠBundle ?): ĠView ? Ġ{ čĊĠĠĠĠĠĠĠ Ġbinding Ġ= ĠData Binding Util . inflate ( in flater , ĠR . layout . fragment _ expense , Ġcontainer , Ġfalse ) čĊĠĠĠĠĠĠĠ Ġbinding . lifecycle Owner Ġ= Ġthis Ġ Ġ// ĠAllows Ġthe Ġbinding Ġto Ġobserve ĠLive Data Ġupdates čĊčĊĠĠĠĠĠĠĠ Ġ// ĠSet Ġup Ġthe ĠViewModel Ġand Ġsimilar čĊĠĠĠĠĠĠĠ Ġval Ġapplication Ġ= Ġrequire NotNull ( this . activity ). application Ġ Ġ// ĠReference Ġto Ġthe Ġapplication Ġcontext čĊĠĠĠĠĠĠĠ Ġval Ġaccount DataSource Ġ= ĠAccount Db . getInstance ( application ). account Db Dao Ġ Ġ// ĠGet Ġa Ġreference Ġto ĠAccount Db Dao , Ġcorrectly Ġlinked Ġwith Ġthe ĠAccount Db čĊĠĠĠĠĠĠĠ Ġval Ġcategory DataSource Ġ= ĠCategory Db . getInstance ( application ). category Db Dao Ġ Ġ// ĠGet Ġa Ġreference Ġto ĠCategory Db Dao , Ġcorrectly Ġlinked Ġwith Ġthe ĠCategory Db čĊĠĠĠĠĠĠĠ Ġval Ġtransaction DataSource Ġ= ĠTransaction Db . getInstance ( application ). transaction Db Dao Ġ Ġ// ĠGet Ġa Ġreference Ġto ĠTransaction Db Dao , Ġcorrectly Ġlinked Ġwith Ġthe ĠTransaction Db čĊĠĠĠĠĠĠĠ Ġval ĠviewModel Factory Ġ= ĠExp ense ViewModel Factory ( account DataSource , Ġcategory DataSource , Ġtransaction DataSource , Ġapplication ) Ġ Ġ// ĠCreate Ġan Ġinstance Ġof Ġthe ĠViewModel Factory Ġassociated Ġwith Ġthis Ġfragment čĊĠĠĠĠĠĠĠ ĠviewModel Ġ= ĠViewModel Provider ( this , ĠviewModel Factory ). get ( Expense ViewModel :: class . java ) Ġ Ġ// ĠGet Ġa Ġreference Ġto Ġthe ĠViewModel Ġassociated Ġwith Ġthis Ġfragment čĊĠĠĠĠĠĠĠ Ġbinding . viewModel Ġ= ĠviewModel čĊčĊĠĠĠĠĠĠĠ ĠviewModel . ensure Selections () Ġ Ġ// ĠIf Ġno Ġaccount Ġor Ġcategory Ġis Ġselected , Ġthis Ġselects Ġthe Ġhighest Ġorder Ġone čĊčĊĠĠĠĠĠĠĠ Ġcal Ġ= ĠCalendar . getInstance () Ġ Ġ// ĠCreates Ġa ĠCalendar Ġinstance , Ġautomatically Ġset Ġto Ġthe Ġcurrent Ġdate čĊčĊĠĠĠĠĠĠĠ Ġ// ĠRe strict s Ġamount Ġinputs Ġto Ġ 2 dp Ġ( and Ġup Ġto Ġorder ĠE + 8 ) čĊĠĠĠĠĠĠĠ Ġbinding . fe Amount . filters Ġ= ĠarrayOf < Input Filter >( Decimal Digits Input Filter ()) čĊčĊĠĠĠĠĠĠĠ Ġ// ĠAccount Ġemoji ĠRecyclerView Ġstuff čĊĠĠĠĠĠĠĠ Ġval Ġaccount Emoji Adapter Ġ= ĠAccount Emoji Adapter Ġ{ Ġa Id Ġ-> Ġ Ġ// Ġselect Account ClickListener čĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . select Account ( a Id ) čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġbinding . fe Account . adapter Ġ= Ġaccount Emoji Adapter Ġ Ġ// ĠThe Ġpoint Ġof Ġthe Ġadapter Ġis Ġto Ġconvert Ġthe Ġapp Ġdata Ġinto Ġobjects / things (/ View Hold ers ) Ġthe ĠRecyclerView Ġcan Ġwork Ġwith čĊĠĠĠĠĠĠĠ ĠviewModel . active Accounts . observe ( view Lifecycle Owner , Ġ{ Ġit ?. let Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġaccount Emoji Adapter . submit List ( it ) Ġ Ġ// ĠWhen Ġsubmit List Ġis Ġcalled , Ġthe ĠList Adapter Ġdiffs Ġthe Ġnew Ġlist Ġagainst Ġthe Ġold Ġone Ġand Ġdetect s Ġitems Ġthat Ġwere Ġadded , Ġremoved , Ġmoved , Ġor Ġchanged . ĠThen Ġthe ĠList Adapter Ġupdates Ġthe Ġitems Ġshown Ġby ĠRecyclerView . čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . fe Account Label . visibility Ġ= ĠView . VISIBLE Ġ Ġ// ĠThese Ġstart Ġout Ġas Ġinvisible Ġso Ġthat Ġthe Ġui Ġdoesn 't Ġjump Ġaround Ġwhile Ġthe Ġre cycl ers Ġload čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . fe Acc Cat Divider . visibility Ġ= ĠView . VISIBLE čĊĠĠĠĠĠĠĠĠĠĠĠ Ġactive Accounts List Ġ= Ġit Ġ Ġ// ĠGet Ġthis Ġso Ġthat Ġautoc lear Ġcan Ġbe Ġapplied Ġin Ġselect Account ClickListener čĊčĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠApply Ġthe Ġautoc lear čĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( account Ġin Ġit ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( account . a Selected ) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . fe Cle ared . isChecked Ġ= Ġaccount . a Aut oc lear čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ} Ġ}) čĊĠĠĠĠĠĠĠ Ġval Ġaccount Recycler Manager Ġ= ĠGrid LayoutManager ( activity , Ġ 7 ) čĊĠĠĠĠĠĠĠ Ġbinding . fe Account . layout Manager Ġ= Ġaccount Recycler Manager Ġ Ġ// ĠUse Ġa Ġgrid Ġto Ġdisplay Ġthe Ġlist _ item 's čĊčĊĠĠĠĠĠĠĠ Ġ// ĠCategory Ġemoji ĠRecyclerView Ġstuff čĊĠĠĠĠĠĠĠ Ġval Ġcategory Emoji Adapter Ġ= ĠCategory Emoji Adapter Ġ{ Ġc Id Ġ-> Ġ Ġ// Ġselect Category ClickListener čĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . select Category ( c Id ) čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġbinding . fe Category . adapter Ġ= Ġcategory Emoji Adapter Ġ Ġ// ĠThe Ġpoint Ġof Ġthe Ġadapter Ġis Ġto Ġconvert Ġthe Ġapp Ġdata Ġinto Ġobjects / things (/ View Hold ers ) Ġthe ĠRecyclerView Ġcan Ġwork Ġwith čĊĠĠĠĠĠĠĠ ĠviewModel . active Categories . observe ( view Lifecycle Owner , Ġ{ Ġit ?. let Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġcategory Emoji Adapter . submit List ( it ) Ġ Ġ// ĠWhen Ġsubmit List Ġis Ġcalled , Ġthe ĠList Adapter Ġdiffs Ġthe Ġnew Ġlist Ġagainst Ġthe Ġold Ġone Ġand Ġdetect s Ġitems Ġthat Ġwere Ġadded , Ġremoved , Ġmoved , Ġor Ġchanged . ĠThen Ġthe ĠList Adapter Ġupdates Ġthe Ġitems Ġshown Ġby ĠRecyclerView . čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . fe Category Label . visibility Ġ= ĠView . VISIBLE Ġ Ġ// ĠThese Ġstart Ġout Ġas Ġinvisible Ġso Ġthat Ġthe Ġui Ġdoesn 't Ġjump Ġaround Ġwhile Ġthe Ġre cycl ers Ġload čĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . fe Cat Amount Divider . visibility Ġ= ĠView . VISIBLE čĊĠĠĠĠĠĠĠ Ġ} Ġ}) čĊĠĠĠĠĠĠĠ Ġval Ġcategory Recycler Manager Ġ= ĠGrid LayoutManager ( activity , Ġ 7 ) čĊĠĠĠĠĠĠĠ Ġbinding . fe Category . layout Manager Ġ= Ġcategory Recycler Manager Ġ Ġ// ĠUse Ġa Ġgrid Ġto Ġdisplay Ġthe Ġlist _ item 's čĊčĊĠĠĠĠĠĠĠ Ġcal Ġ= ĠCalendar . getInstance () Ġ Ġ// ĠCreates Ġa ĠCalendar Ġinstance , Ġautomatically Ġset Ġto Ġthe Ġcurrent Ġdate čĊčĊĠĠĠĠĠĠĠ Ġ// ĠT ries Ġto Ġadd Ġan Ġexpense . ĠIf Ġsuccessful , Ġback s Ġout Ġof Ġthe Ġfragment čĊĠĠĠĠĠĠĠ Ġbinding . fe Ok . setOnClickListener Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( make Expense ()) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfind Nav Controller (). pop Back Stack () Ġ Ġ// ĠPress Ġback čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġ// ĠT ries Ġto Ġadd Ġan Ġexpense . ĠIf Ġsuccessful , Ġclears Ġthe Ġamount / note Ġfields Ġand Ġa Ġtoast Ġdecl ares Ġthe Ġexpense Ġwas Ġadded čĊĠĠĠĠĠĠĠ Ġbinding . fe Ok . setOn Long ClickListener { čĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( make Expense ()) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . fe Amount . text . clear () čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . fe Note . text . clear () čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( context , Ġ" Expense Ġadded ", ĠToast . LENGTH _ SHORT ). show () Ġ// todo Ġextract čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue Ġ Ġ// ĠNot ifies Ġthe Ġphone Ġthat Ġthe Ġlong Ġclick Ġwas Ġconsumed čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġbinding . fe Cancel . setOnClickListener { čĊĠĠĠĠĠĠĠĠĠĠĠ Ġhide Keyboard () čĊĠĠĠĠĠĠĠĠĠĠĠ Ġfind Nav Controller (). pop Back Stack () Ġ Ġ// ĠPress Ġback čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġreturn Ġbinding . root čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġ/** ĠChecks Ġif Ġan Ġamount Ġwas Ġentered , Ġthen Ġmakes Ġan Ġexpense Ġand Ġadds Ġit Ġto Ġthe ĠTransaction Db Ġ*/ čĊĠĠĠ Ġprivate Ġfun Ġmake Expense () Ġ: ĠBoolean Ġ{ čĊĠĠĠĠĠĠĠ Ġhide Keyboard () čĊčĊĠĠĠĠĠĠĠ Ġif Ġ( binding . fe Amount . text . isBlank ()) Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( context , Ġ" Enter Ġan Ġamount ", ĠToast . LENGTH _ SHORT ). show () Ġ// todo Ġextract čĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠĠĠĠĠ Ġval Ġnew Expense Ġ= ĠTransaction () čĊĠĠĠĠĠĠĠ Ġnew Expense . t Type Ġ= Ġ 2 Ġ Ġ// Ġ 2 Ġfor Ġexpense čĊĠĠĠĠĠĠĠ Ġnew Expense . t Date Ġ= ĠLocalDateTime . of Instant ( cal . to Instant (), ĠZone Id . system Default ()). to LocalDate (). to Epoch Day () čĊĠĠĠĠĠĠĠ Ġnew Expense . t Amount Ġ= Ġ-( binding . fe Amount . text . toString (). toDouble ()) čĊĠĠĠĠĠĠĠ Ġnew Expense . t Note Ġ= Ġbinding . fe Note . text . toString () čĊĠĠĠĠĠĠĠ Ġnew Expense . t Cle ared Ġ= Ġbinding . fe Cle ared . isChecked čĊčĊĠĠĠĠĠĠĠ ĠviewModel . insert Expense ( new Expense ) čĊĠĠĠĠĠĠĠ Ġreturn Ġtrue čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġ/** ĠInitial ise Ġviews Ġand Ġset Ġup Ġthe ĠonClick Listeners Ġ*/ čĊĠĠĠ Ġoverride Ġfun Ġon View Created ( view : ĠView , ĠsavedInstanceState : ĠBundle ?) Ġ{ čĊĠĠĠĠĠĠĠ Ġsuper . on View Created ( view , ĠsavedInstanceState ) čĊčĊĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġstuff Ġused Ġto Ġchoose Ġthe Ġdate Ġready čĊĠĠĠĠĠĠĠ Ġval Ġsettings Shared Prefs Ġ= ĠPreference Manager . getDefault SharedPreferences ( context ) čĊĠĠĠĠĠĠĠ Ġval Ġsettings Date Ġ= Ġsettings Shared Prefs . getString (" settings _ date ", Ġ"") čĊĠĠĠĠĠĠĠ Ġval ĠdateFormat Ġ= Ġwhen Ġ( settings Date ) Ġ{ Ġ Ġ// Ġhttps :// developer . android . com / reference / java / text / SimpleDateFormat ĠIf Ġusing Ġnon ĠLocale . EN GL ISH Ġlocales Ġlater , Ġmake Ġsure Ġthat Ġspecial Ġcharacters Ġdon 't Ġmess Ġthings Ġup , Ġfrom Ġacc ents Ġto Ġch inese Ġcharacters čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" d my Slash " Ġ-> ĠSimpleDateFormat (" dd / MM / yy ", ĠLocale . EN GL ISH ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" d my Dot " Ġ-> ĠSimpleDateFormat (" dd . MM . yy ", ĠLocale . EN GL ISH ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" md y Slash " Ġ-> ĠSimpleDateFormat (" MM / dd / yy ", ĠLocale . EN GL ISH ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" md y Dot " Ġ-> ĠSimpleDateFormat (" MM . dd . yy ", ĠLocale . EN GL ISH ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" y md Slash " Ġ-> ĠSimpleDateFormat (" yy / MM / dd ", ĠLocale . EN GL ISH ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" y md Dot " Ġ-> ĠSimpleDateFormat (" yy . MM . dd ", ĠLocale . EN GL ISH ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠSimpleDateFormat (" dd / MM / yy ", ĠLocale . EN GL ISH ) čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġval Ġdate Picker Dialog Ġ= ĠDate Picker Dialog ( Ġ Ġ// ĠThis Ġdate Ġpicker Ġdialog Ġis Ġopened Ġin Ġthe ĠonClick Listener Ġfor Ġthe Ġdate Ġbutton Ġbelow čĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire NotNull ( activity ), Ġ{ Ġ_, Ġyear , Ġmonth , Ġday OfMonth Ġ-> Ġ Ġ// ĠThis Ġsecond Ġargument Ġis Ġa ĠDate Picker Dialog . On Date Set Listener . ĠSo , Ġupdate Ġthe Ġ" cal " ĠCalendar Ġinstance , Ġand Ġthe Ġtext Ġof Ġthe Ġbutton , Ġwith Ġthe Ġchosen Ġdate čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcal . set ( year , Ġmonth , Ġday OfMonth ) čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . fe Date . text Ġ= ĠdateFormat . format ( cal . time ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}, čĊĠĠĠĠĠĠĠĠĠĠĠ Ġcal . get ( Calendar . YEAR ), Ġcal . get ( Calendar . MONTH ), Ġcal . get ( Calendar . DAY _ OF _ MONTH ) Ġ Ġ// ĠN eeded Ġto Ġopen Ġthe Ġdate Picker Ġto Ġthe Ġdate Ġof Ġcal Ġ( init ially Ġthe Ġcurrent Ġdate , Ġthen Ġthe Ġchosen Ġdate ) čĊĠĠĠĠĠĠĠ Ġ) čĊĠĠĠĠĠĠĠ Ġdate Picker Dialog . date Picker . max Date Ġ= ĠSystem . currentTimeMillis () Ġ Ġ// ĠDis allow Ġchoosing Ġfuture Ġdates čĊčĊĠĠĠĠĠĠĠ Ġ// ĠGive Ġthe Ġdate Ġbutton Ġthe Ġinitial Ġdate , Ġand Ġset Ġits ĠonClick Listener Ġto Ġopen Ġthe Ġdate Picker Ġdialog Ġ( which Ġupdates Ġthis Ġsame Ġbutton Ġitself ) čĊĠĠĠĠĠĠĠ Ġbinding . fe Date . text Ġ= ĠdateFormat . format ( cal . time ) čĊĠĠĠĠĠĠĠ Ġbinding . fe Date . setOnClickListener Ġ{ Ġdate Picker Dialog . show () Ġ} čĊĠĠĠ Ġ} č Ċ }