/* Ċ Ġ* ĠCopyright Ġ 2 0 2 1 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* Ġ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 Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttps :// 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 dev challenge Ċ Ċ import Ġandroid . os . Bundle Ċ import Ġandroidx . activity . compose . setContent Ċ import Ġandroidx . appcompat . app . AppCompatActivity Ċ import Ġandroidx . compose . animation . core . Linear E asing Ċ import Ġandroidx . compose . animation . core . animate Float Ċ import Ġandroidx . compose . animation . core . t ween Ċ import Ġandroidx . compose . animation . core . update Transition Ċ import Ġandroidx . compose . foundation . Canvas Ċ import Ġandroidx . compose . foundation . layout . Box Ċ import Ġandroidx . compose . foundation . layout . Column Ċ import Ġandroidx . compose . foundation . layout . Row Ċ import Ġandroidx . compose . foundation . layout . fill MaxSize Ċ import Ġandroidx . compose . foundation . layout . fill Max Width Ċ import Ġandroidx . compose . foundation . layout . padding Ċ import Ġandroidx . compose . foundation . layout . wrap Content Height Ċ import Ġandroidx . compose . material . Button Ċ import Ġandroidx . compose . material . Icon Ċ import Ġandroidx . compose . material . IconButton Ċ import Ġandroidx . compose . material . Material Theme Ċ import Ġandroidx . compose . material . Surface Ċ import Ġandroidx . compose . material . Text Ċ import Ġandroidx . compose . material . icons . Icons Ċ import Ġandroidx . compose . material . icons . filled . Expand Less Ċ import Ġandroidx . compose . material . icons . filled . Expand More Ċ import Ġandroidx . compose . runtime . Composable Ċ import Ġandroidx . compose . runtime . getValue Ċ import Ġandroidx . compose . runtime . li ved ata . observe As State Ċ import Ġandroidx . compose . ui . Alignment Ċ import Ġandroidx . compose . ui . Modifier Ċ import Ġandroidx . compose . ui . geometry . Offset Ċ import Ġandroidx . compose . ui . geometry . Size Ċ import Ġandroidx . compose . ui . graphics . Color Ċ import Ġandroidx . compose . ui . graphics . draw scope . Stroke Ċ import Ġandroidx . compose . ui . text . TextStyle Ċ import Ġandroidx . compose . ui . text . style . Text Align Ċ import Ġandroidx . compose . ui . tool ing . preview . Preview Ċ import Ġandroidx . compose . ui . unit . dp Ċ import Ġandroidx . compose . ui . unit . sp Ċ import Ġandroidx . lifecycle . view model . compose . viewModel Ċ import Ġcom . example . android dev challenge . ui . theme . My Theme Ċ import Ġkotlin . math . abs Ċ Ċ class ĠMainActivity Ġ: ĠAppCompatActivity () Ġ{ ĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĠĠĠĠĠĠĠ Ġset Content Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMy Theme Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMy App () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ // ĠStart Ġbuilding Ġyour Ġapp Ġhere ! Ċ @ Composable Ċ fun ĠMy App () Ġ{ ĊĠĠĠ ĠSurface ( modifier Ġ= ĠModifier . fill MaxSize ( 1 f ), Ġcolor Ġ= ĠMaterial Theme . colors . background ) Ġ{ ĊĠĠĠĠĠĠĠ ĠCounter () ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Preview (" Light ĠTheme ", Ġwidth Dp Ġ= Ġ 3 6 0 , Ġheight Dp Ġ= Ġ 6 4 0 ) Ċ @ Composable Ċ fun ĠLight Preview () Ġ{ ĊĠĠĠ ĠMy Theme Ġ{ ĊĠĠĠĠĠĠĠ ĠMy App () ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Preview (" Dark ĠTheme ", Ġwidth Dp Ġ= Ġ 3 6 0 , Ġheight Dp Ġ= Ġ 6 4 0 ) Ċ @ Composable Ċ fun ĠDark Preview () Ġ{ ĊĠĠĠ ĠMy Theme ( dark Theme Ġ= Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠ ĠMy App () ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Composable Ċ fun ĠCounter ( main ViewModel : ĠMain ViewModel Ġ= ĠviewModel ()) Ġ{ ĊĠĠĠ Ġval Ġminutes : ĠInt Ġby Ġmain ViewModel . minutes . observe As State ( 0 ) ĊĠĠĠ Ġval Ġseconds : ĠInt Ġby Ġmain ViewModel . seconds . observe As State ( 0 ) ĊĠĠĠ Ġval Ġcount : ĠInt Ġby Ġmain ViewModel . time . observe As State ( 0 ) ĊĠĠĠ Ġval Ġstate : ĠMain ViewModel . Timer Progress Ġby Ġmain ViewModel . timer Progress . observe As State ( ĊĠĠĠĠĠĠĠ ĠMain ViewModel . Timer Progress . SETTING ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġval Ġtransition Ġ= Ġupdate Transition ( state ) ĊĠĠĠ Ġval Ġangle Offset Ġby Ġtransition . animate Float ( ĊĠĠĠĠĠĠĠ Ġtransition Spec Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġt ween ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay Millis Ġ= Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġduration Millis Ġ= Ġmain ViewModel . max Time Ġ* Ġ 1 0 0 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġeasing Ġ= ĠLinear E asing ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ) Ġ{ Ġprogress Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( progress Ġ== ĠMain ViewModel . Timer Progress . SETTING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ 3 6 0 f ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 f ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ ĠColumn ( Modifier . fill MaxSize ()) Ġ{ ĊĠĠĠĠĠĠĠ ĠRow ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠModifier ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. fill Max Width () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. wrap Content Height () ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNumber Setting ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier . weight ( 0 . 5 f ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnumber Ġ= Ġminutes , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Increment Ġ= Ġ{ Ġmain ViewModel . increment Minutes () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon De crement Ġ= Ġ{ Ġmain ViewModel . decrement Minutes () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNumber Setting ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier . weight ( 0 . 5 f ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnumber Ġ= Ġseconds , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Increment Ġ= Ġ{ Ġmain ViewModel . increment Seconds () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon De crement Ġ= Ġ{ Ġmain ViewModel . decrement Seconds () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠRow ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠModifier ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. fill Max Width () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. wrap Content Height () ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠButton ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. weight ( 0 . 5 f ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. padding ( 3 2 . dp ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonClick Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmain ViewModel . start Timer () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠText ( text Ġ= Ġ" start ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠButton ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. weight ( 0 . 5 f ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. padding ( 3 2 . dp ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonClick Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmain ViewModel . stop Timer () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠText ( text Ġ= Ġ" stop ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠButton ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. weight ( 0 . 5 f ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. padding ( 3 2 . dp ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonClick Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmain ViewModel . clear Timer () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠText ( text Ġ= Ġ" clear ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠBox ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. fill MaxSize (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Alignment Ġ= ĠAlignment . Center , ĊĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCanvas ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. fill MaxSize () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. padding ( 3 2 . dp ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmiddle Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOffset ( size . width Ġ/ Ġ 2 , Ġsize . height Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdraw Circle ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcolor Ġ= ĠColor . Blue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcenter Ġ= Ġmiddle , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġradius Ġ= Ġsize . min Dimension Ġ/ Ġ 2 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstyle Ġ= ĠSt roke ( 8 . dp . to Px ()), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdraw Arc ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠColor . Red , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 2 7 0 f , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġangle Offset , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuse Center Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsize Ġ= ĠSize ( size . min Dimension , Ġsize . min Dimension ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtop Left Ġ= ĠOffset ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġabs (( size . min Dimension Ġ/ Ġ 2 ) Ġ- Ġ( size . width Ġ/ Ġ 2 )), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġabs (( size . min Dimension Ġ/ Ġ 2 ) Ġ- Ġ( size . height Ġ/ Ġ 2 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstyle Ġ= ĠSt roke ( 8 . dp . to Px ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtime Text Ġ= ĠString . format ("% 0 2 d :% 0 2 d ", Ġcount Ġ/ Ġ 6 0 , Ġcount Ġ% Ġ 6 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠText ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtext Ġ= Ġtime Text , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier . padding ( start Ġ= Ġ 0 . dp , Ġtop Ġ= Ġ 0 . dp , Ġend Ġ= Ġ 0 . dp , Ġbottom Ġ= Ġ 1 6 . dp ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstyle Ġ= ĠTextStyle ( fontSize Ġ= Ġ 8 0 . sp ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠtextAlign Ġ= ĠText Align . Center ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Composable Ċ fun ĠNumber Setting ( ĊĠĠĠ Ġmodifier : ĠModifier , Ċ // ĠĠĠ Ġenabled : ĠBoolean , ĊĠĠĠ Ġnumber : ĠInt , ĊĠĠĠ Ġon Increment : Ġ() Ġ-> ĠUnit , ĊĠĠĠ Ġon De crement : Ġ() Ġ-> ĠUnit Ċ ) Ġ{ ĊĠĠĠ Ġval Ġtime Ġ= ĠString . format ("% 0 2 d ", Ġnumber ) ĊĠĠĠ ĠColumn ( ĊĠĠĠĠĠĠĠ Ġmodifier Ġ= Ġmodifier ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. fill Max Width () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. wrap Content Height () ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ ĠIcon Button ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠonClick Ġ= Ġ{ Ġon Increment () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier . fill Max Width () ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIcon ( Icons . Default . Expand Less , Ġ" less ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠText ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtext Ġ= Ġtime , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier . fill Max Width (), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠtextAlign Ġ= ĠText Align . Center , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstyle Ġ= ĠTextStyle ( fontSize Ġ= Ġ 6 4 . sp ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠIcon Button ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠonClick Ġ= Ġ{ Ġon De crement () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier . fill Max Width () ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIcon ( Icons . Default . Expand More , Ġ" more ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ