/* Ċ Ġ* ĠCopyright Ġ 2 0 1 8 ĠGoogle ĠInc . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġcom . example . android . my address book Ċ Ċ import Ġkotlinx . android . synt hetic . main . activity _ contacts .* Ċ import Ġkotlinx . android . synt hetic . main . content _ contacts .* Ċ import Ġandroid . annotation . Suppress Lint Ċ import Ġandroid . arch . lifecycle . Observer Ċ import Ġandroid . arch . lifecycle . ViewModel Providers Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . SharedPreferences Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . support . v 7 . app . AlertDialog Ċ import Ġandroid . support . v 7 . app . AppCompatActivity Ċ import Ġandroid . support . v 7 . widget . Divider Item Decoration Ċ import Ġandroid . support . v 7 . widget . RecyclerView Ċ import Ġandroid . support . v 7 . widget . helper . Item Touch Helper Ċ import Ġandroid . text . Editable Ċ import Ġandroid . text . Text Watcher Ċ import Ġandroid . util . Log Ċ import Ġandroid . util . Patterns Ċ import Ġandroid . view . LayoutInflater Ċ import Ġandroid . view . Menu Ċ import Ġandroid . view . MenuItem Ċ import Ġandroid . view . View Ċ import Ġandroid . view . ViewGroup Ċ import Ġandroid . widget . EditText Ċ import Ġandroid . widget . TextView Ċ import Ġandroid . widget . Toast Ċ import Ġcom . example . android . model . Contact Ċ Ċ import Ġcom . google . gson . Gson Ċ import Ġkotlinx . android . synt hetic . main . contact _ list _ item . view .* Ċ import Ġkotlinx . android . synt hetic . main . input _ contact _ dialog . view .* Ċ Ċ import Ġorg . json . JSONArray Ċ import Ġorg . json . JSONException Ċ Ċ import Ġjava . io . IOException Ċ import Ġjava . util . ArrayList Ċ Ċ class ĠContact s Activity Ġ: ĠAppCompatActivity (), ĠText Watcher Ġ{ ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm Contacts : ĠArrayList < Contact > ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm Adapter : ĠContact s Adapter ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm Prefs : ĠSharedPreferences ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm FirstName Edit : ĠEditText ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm LastName Edit : ĠEditText ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm Email Edit : ĠEditText ĊĊĠĠĠ Ġprivate Ġvar Ġm Entry Valid Ġ= Ġfalse ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġcontact ViewModel : ĠContact ViewModel ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĠĠĠĠĠĠĠ ĠsetContentView ( R . layout . activity _ contacts ) ĊĊĠĠĠĠĠĠĠ Ġm Prefs Ġ= Ġget Preferences ( Context . MODE _ PRIVATE ) ĊĠĠĠĠĠĠĠ Ġm Contacts Ġ= Ġload Contacts () ĊĠĠĠĠĠĠĠ Ġm Adapter Ġ= ĠContact s Adapter ( m Contacts ) ĊĊĠĠĠĠĠĠĠ Ġset Support ActionBar ( toolbar ) ĊĠĠĠĠĠĠĠ Ġsetup RecyclerView () ĊĊĠĠĠĠĠĠĠ Ġcontact ViewModel Ġ= ĠViewModel Providers . of ( this ). get ( Contact ViewModel :: class . java ) ĊĊĠĠĠĠĠĠĠ Ġsubscribe Contacts (); ĊĊĠĠĠĠĠĠĠ Ġfab . setOnClickListener Ġ{ Ġshow Add Contact Dialog (- 1 ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsubscribe Contacts () Ġ{ ĊĠĠĠĠĠĠĠ Ġcontact ViewModel . contacts List . observe ( this , ĠObserver < List < Contact >> ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . clear Contacts () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . addAll Contacts ( result ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . notify DataSet Changed () ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġload Contacts (): ĠArrayList < Contact > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠArrayList () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠS aves Ġthe Ġcontacts Ġto ĠSharedPreferences Ġby Ġserial izing Ġthem Ġwith ĠGson . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġsave Contacts () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġeditor Ġ= Ġm Prefs . edit () ĊĠĠĠĠĠĠĠ Ġeditor . clear () ĊĠĠĠĠĠĠĠ Ġval Ġcontact Set Ġ= Ġm Contacts . map Ġ{ ĠGson (). toJson ( it ) Ġ}. toSet () ĊĠĠĠĠĠĠĠ Ġeditor . putString Set ( CONTACT _ KEY , Ġcontact Set ) ĊĠĠĠĠĠĠĠ Ġeditor . apply () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSets Ġup Ġthe ĠRecyclerView : Ġempty Ġdata Ġset , Ġitem Ġdiv iders , Ġswipe Ġto Ġdelete . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġsetup RecyclerView () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// val Ġre cyclerView Ġ= ĠfindViewById < RecyclerView >( R . id . contact _ list ) ĊĊĠĠĠĠĠĠĠ Ġcontact _ list . addItem Decoration ( Divider Item Decoration ( this , ĠDiv ider Item Decoration . VERTICAL )) ĊĠĠĠĠĠĠĠ Ġcontact _ list . adapter Ġ= Ġm Adapter ĊĊĠĠĠĠĠĠĠ Ġ// ĠImplements Ġswipe Ġto Ġdelete ĊĠĠĠĠĠĠĠ Ġval Ġhelper Ġ= ĠItem Touch Helper ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠItem Touch Helper . Simple Callback ( 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠItem Touch Helper . LEFT Ġor ĠItem Touch Helper . RIGHT ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Move ( r V : ĠRecyclerView , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewHolder : ĠRecyclerView . ViewHolder , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget : ĠRecyclerView . ViewHolder ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Sw ip ed ( view Holder : ĠRecyclerView . ViewHolder , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdirection : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġposition Ġ= ĠviewHolder . adapter Position ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontact Ġ= Ġm Contacts . remove At ( position ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontact ViewModel . delete ( contact ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . notify Item Removed ( position ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsave Contacts () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠ Ġhelper . attach To RecyclerView ( contact _ list ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠShows Ġthe ĠAlertDialog Ġfor Ġentering Ġa Ġnew Ġcontact Ġand Ġperforms Ġvalidation ĊĠĠĠĠ Ġ* Ġon Ġthe Ġuser Ġinput . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġcontact Position ĠThe Ġposition Ġof Ġthe Ġcontact Ġbeing Ġedited , Ġ- 1 ĊĠĠĠĠ Ġ* Ġif Ġthe Ġuser Ġis Ġcreating Ġa Ġnew Ġcontact . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Suppress Lint (" Inf late Params ") ĊĠĠĠ Ġprivate Ġfun Ġshow Add Contact Dialog ( contact Position : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠIn fl ates Ġthe Ġdialog Ġview ĊĠĠĠĠĠĠĠ Ġval Ġdialog View Ġ= ĠLayoutInflater . from ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. inflate ( R . layout . input _ contact _ dialog , Ġnull ) ĊĊĠĠĠĠĠĠĠ Ġm FirstName Edit Ġ= Ġdialog View . edit text _ firstname ĊĠĠĠĠĠĠĠ Ġm LastName Edit Ġ= Ġdialog View . edit text _ lastname ĊĠĠĠĠĠĠĠ Ġm Email Edit Ġ= Ġdialog View . edit text _ email ĊĊĠĠĠĠĠĠĠ Ġ// ĠList ens Ġto Ġtext Ġchanges Ġto Ġvalidate Ġafter Ġeach Ġkey Ġpress ĊĠĠĠĠĠĠĠ Ġm FirstName Edit . add TextChanged Listener ( this ) ĊĠĠĠĠĠĠĠ Ġm LastName Edit . add TextChanged Listener ( this ) ĊĠĠĠĠĠĠĠ Ġm Email Edit . add TextChanged Listener ( this ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠChecks Ġif Ġthe Ġuser Ġis Ġediting Ġan Ġexisting Ġcontact ĊĠĠĠĠĠĠĠ Ġval Ġediting Ġ= Ġcontact Position Ġ> Ġ- 1 ĊĊĠĠĠĠĠĠĠ Ġval Ġdialog Title Ġ= Ġif Ġ( editing ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠgetString ( R . string . edit _ contact ) ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠgetString ( R . string . new _ contact ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠBuilds Ġthe ĠAlertDialog Ġand Ġsets Ġthe Ġcustom Ġview . ĠPass Ġnull Ġfor ĊĠĠĠĠĠĠĠ Ġ// Ġthe Ġpositive Ġand Ġnegative Ġbuttons , Ġas Ġyou Ġwill Ġoverride Ġthe Ġbutton ĊĠĠĠĠĠĠĠ Ġ// Ġp resses Ġmanually Ġto Ġperform Ġvalidation Ġbefore Ġclosing Ġthe Ġdialog ĊĠĠĠĠĠĠĠ Ġval Ġbuilder Ġ= ĠAlertDialog . Builder ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setView ( dialog View ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setTitle ( dialog Title ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Positive Button ( R . string . save , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Negative Button ( R . string . cancel , Ġnull ) ĊĊĠĠĠĠĠĠĠ Ġval Ġdialog Ġ= Ġbuilder . show () ĊĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġcontact Ġis Ġbeing Ġedited , Ġpop ulates Ġthe ĠEditText Ġwith Ġthe Ġold ĊĠĠĠĠĠĠĠ Ġ// Ġinformation ĊĠĠĠĠĠĠĠ Ġif Ġ( editing ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġedited Contact Ġ= Ġm Contacts [ contact Position ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm FirstName Edit . setText ( edited Contact . firstName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm FirstName Edit . isEnabled Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm LastName Edit . setText ( edited Contact . lastName ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm LastName Edit . isEnabled Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Email Edit . setText ( edited Contact . email ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠOverrides Ġthe Ġ" Save " Ġbutton Ġpress Ġand Ġcheck Ġfor Ġvalid Ġinput ĊĠĠĠĠĠĠĠ Ġdialog . get Button ( AlertDialog . BUTTON _ POSITIVE ). setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġinput Ġis Ġvalid , Ġcreates Ġand Ġsaves Ġthe Ġnew Ġcontact , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġor Ġreplaces Ġit Ġif Ġthe Ġcontact Ġis Ġbeing Ġedited ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Entry Valid ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( editing ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġedited Contact Ġ= Ġm Contacts [ contact Position ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġedited Contact . email Ġ= Ġm Email Edit . text . toString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Contacts [ contact Position ] Ġ= Ġedited Contact ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontact ViewModel . update ( edited Contact ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . notify Item Changed ( contact Position ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Contact Ġ= ĠContact ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm FirstName Edit . text . toString (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm LastName Edit . text . toString (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Email Edit . text . toString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Contacts . add ( new Contact ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontact ViewModel . insert ( new Contact ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . notify Item Inserted ( m Contacts . size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsave Contacts () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdialog . dismiss () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠOtherwise , Ġshows Ġan Ġerror ĠToast ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( this @ Contacts Activity , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . contact _ not _ valid , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . LENGTH _ SHORT ). show () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġoverride Ġfun ĠonCreate Options Menu ( menu : ĠMenu ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠInf late Ġthe Ġmenu ; Ġthis Ġadds Ġitems Ġto Ġthe Ġaction Ġbar Ġif Ġit Ġis Ġpresent . ĊĠĠĠĠĠĠĠ Ġmenu Inflater . inflate ( R . menu . menu _ contacts , Ġmenu ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Options ItemSelected ( item : ĠMenuItem ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠHandle Ġaction Ġbar Ġitem Ġclicks Ġhere . ĠThe Ġaction Ġbar Ġwill ĊĠĠĠĠĠĠĠ Ġ// Ġautomatically Ġhandle Ġclicks Ġon Ġthe ĠHome / Up Ġbutton , Ġso Ġlong ĊĠĠĠĠĠĠĠ Ġ// Ġas Ġyou Ġspecify Ġa Ġparent Ġactivity Ġin ĠAndroid Manifest . xml . ĊĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġitem . itemId ĊĊĠĠĠĠĠĠĠ Ġwhen Ġ( id ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . action _ clear Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclear Contacts () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . action _ generate Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgenerate Contacts () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . action _ sort _ first Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Contacts . sortBy Ġ{ Ġit . firstName Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . notify DataSet Changed () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . action _ sort _ last Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Contacts . sortBy Ġ{ Ġit . lastName Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . notify DataSet Changed () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . on Options ItemSelected ( item ) ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠClear s Ġthe Ġcontacts Ġfrom ĠSharedPreferences Ġand Ġthe Ġadapter , Ġcalled Ġfrom ĊĠĠĠĠ Ġ* Ġthe Ġoptions Ġmenu . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġclear Contacts () Ġ{ ĊĠĠĠĠĠĠĠ Ġm Contacts . clear () ĊĠĠĠĠĠĠĠ Ġsave Contacts () ĊĠĠĠĠĠĠĠ Ġm Adapter . notify DataSet Changed () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGenerates Ġmock Ġcontact Ġdata Ġto Ġpopulate Ġthe ĠUI Ġfrom Ġa ĠJSON Ġfile Ġin Ġthe ĊĠĠĠĠ Ġ* Ġassets Ġdirectory , Ġcalled Ġfrom Ġthe Ġoptions Ġmenu . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġgenerate Contacts () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontacts String Ġ= Ġread Contact Json File () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontacts Json Ġ= ĠJSONArray ( contacts String ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġcontacts Json . length ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontact Json Ġ= Ġcontacts Json . getJSONObject ( i ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontact Ġ= ĠContact ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontact Json . getString (" first _ name "), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontact Json . getString (" last _ name "), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontact Json . getString (" email ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" generate Contacts : Ġ" Ġ+ Ġcontact . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Contacts . add ( contact ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . notify DataSet Changed () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsave Contacts () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠJSON Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReads Ġa Ġfile Ġfrom Ġthe Ġassets Ġdirectory Ġand Ġreturns Ġit Ġas Ġa Ġstring . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠThe Ġresulting Ġstring . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġread Contact Json File (): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcontacts String : ĠString ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠinputStream Ġ= Ġassets . open (" mock _ contacts . json ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsize Ġ= ĠinputStream . available () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠByteArray ( size ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠinputStream . read ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠinputStream . close () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontacts String Ġ= ĠString ( buffer ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġcontacts String ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠOverride Ġmethods Ġfor Ġthe ĠText Watcher Ġinterface , Ġused Ġto Ġvalidate Ġuser ĊĠĠĠĠ Ġ* Ġinput . ĊĠĠĠĠ Ġ*/ ĊĊĊĠĠĠ Ġoverride Ġfun Ġbefore TextChanged ( char Sequence : ĠCharSequence , Ġi : ĠInt , Ġi 1 : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi 2 : ĠInt ) Ġ{ ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon TextChanged ( char Sequence : ĠCharSequence , Ġi : ĠInt , Ġi 1 : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi 2 : ĠInt ) Ġ{ ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠValid ates Ġthe Ġuser Ġinput Ġwhen Ġadding Ġa Ġnew Ġcontact Ġeach Ġtime Ġthe Ġtest ĊĠĠĠĠ Ġ* Ġis Ġchanged . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġeditable ĠThe Ġtext Ġthat Ġwas Ġchanged . ĠIt Ġis Ġnot Ġused Ġas Ġyou Ġget Ġthe ĊĠĠĠĠ Ġ* Ġtext Ġfrom Ġmember Ġvariables . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġafter TextChanged ( editable : ĠEdit able ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnot Empty : ĠTextView . () Ġ-> ĠBoolean Ġ= Ġ{ Ġtext . isNotEmpty () Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġis Email : ĠTextView . () Ġ-> ĠBoolean Ġ= Ġ{ ĠPattern s . EMAIL _ ADDRESS . matcher ( text ). matches () Ġ} ĊĊĠĠĠĠĠĠĠ Ġm Entry Valid Ġ= Ġm FirstName Edit . validate With ( validator Ġ= Ġnot Empty ) Ġand ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm LastName Edit . validate With ( validator Ġ= Ġnot Empty ) Ġand ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Email Edit . validate With ( validator Ġ= Ġis Email ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinner Ġclass ĠContact s Adapter Ġinternal Ġconstructor ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġm Contacts : ĠArrayList < Contact >) Ġ: ĠRecyclerView . Adapter < Contacts Adapter . ViewHolder >() Ġ{ ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonCreate ViewHolder ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparent : ĠViewGroup , Ġview Type : ĠInt ): ĠViewHolder Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġview Ġ= ĠLayoutInflater . from ( parent . context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. inflate ( R . layout . contact _ list _ item , Ġparent , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠViewHolder ( view ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Bind ViewHolder ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġholder : ĠViewHolder , Ġposition : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Contact Ġ= Ġm Contacts [ position ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠfullName Ġ= Ġcurrent Contact . firstName Ġ+ Ġ" Ġ" Ġ+ Ġcurrent Contact . lastName ĊĠĠĠĠĠĠĠĠĠĠĠ Ġholder . name Label . text Ġ= ĠfullName ĊĠĠĠĠĠĠĠĠĠĠĠ Ġholder . email Label . text Ġ= Ġcurrent Contact . email ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠgetItem Count (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġm Contacts . size ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġadd All Contacts ( contacts Ġ: ĠList < Contact >? Ġ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( contacts Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Contacts . addAll ( contacts ); ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġclear Contacts (){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Contacts . clear () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġinternal Ġinner Ġclass ĠViewHolder ( item View : ĠView ) Ġ: ĠRecyclerView . ViewHolder ( item View ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġname Label : ĠTextView Ġ= ĠitemView . text view _ name ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġemail Label : ĠTextView Ġ= ĠitemView . text view _ email ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠitemView . setOnClickListener Ġ{ Ġshow Add Contact Dialog ( adapter Position ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠCONT ACT _ KEY Ġ= Ġ" contact _ key " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠTAG Ġ= ĠContact s Activity :: class . java . simple Name ĊĠĠĠ Ġ} Ċ } Ċ