package Ġcom . example . play . ui Ċ Ċ import Ġandroidx . annotation . Float Range Ċ import Ġandroidx . compose . animation . core . Anim atable Ċ import Ġandroidx . compose . animation . core . Animation Spec Ċ import Ġandroidx . compose . animation . core . Spring Spec Ċ import Ġandroidx . compose . foundation . border Ċ import Ġandroidx . compose . foundation . layout . Box Ċ import Ġandroidx . compose . foundation . layout . Box Scope Ċ import Ġandroidx . compose . foundation . layout . Column Ċ import Ġandroidx . compose . foundation . layout . Spacer Ċ import Ġandroidx . compose . foundation . layout . fill MaxSize Ċ import Ġandroidx . compose . foundation . layout . height Ċ import Ġandroidx . compose . foundation . layout . padding Ċ import Ġandroidx . compose . foundation . selection . selectable Ċ import Ġandroidx . compose . foundation . shape . Rounded Corner Shape Ċ import Ġandroidx . compose . material . Icon Ċ import Ġandroidx . compose . material . Material Theme Ċ import Ġandroidx . compose . material . Text Ċ import Ġandroidx . compose . runtime . Composable Ċ import Ġandroidx . compose . runtime . La unched Effect Ċ import Ġandroidx . compose . runtime . getValue Ċ import Ġandroidx . compose . runtime . remember Ċ import Ġandroidx . compose . ui . Alignment Ċ import Ġandroidx . compose . ui . Modifier Ċ import Ġandroidx . compose . ui . draw . clip Ċ import Ġandroidx . compose . ui . graphics . Color Ċ import Ġandroidx . compose . ui . graphics . Shape Ċ import Ġandroidx . compose . ui . graphics . Transform Origin Ċ import Ġandroidx . compose . ui . graphics . graphics Layer Ċ import Ġandroidx . compose . ui . layout . Layout Ċ import Ġandroidx . compose . ui . layout . Measure Result Ċ import Ġandroidx . compose . ui . layout . Measure Scope Ċ import Ġandroidx . compose . ui . layout . Place able Ċ import Ġandroidx . compose . ui . layout . layout Id Ċ import Ġandroidx . compose . ui . res . string Resource Ċ import Ġandroidx . compose . ui . unit . Dp Ċ import Ġandroidx . compose . ui . unit . dp Ċ import Ġandroidx . compose . ui . util . lerp Ċ import Ġandroidx . navigation . Nav Host Controller Ċ import Ġandroidx . navigation . compose . current Back Stack Entry As State Ċ import Ġcom . example . play . anim . get Bottom Nav Tint State Ċ import Ġcom . example . play . anim . get Progress State Ċ import Ġcom . example . play . theme . Play Theme Ċ import Ġcom . example . play . ui . components . Play Surface Ċ import Ġcom . google . ac comp an ist . in sets . navigation Bars Padding Ċ import Ġjava . util . Locale Ċ Ċ private Ġval ĠText Icon Spacing Ġ= Ġ 5 . dp Ċ private Ġval ĠBottom Nav Height Ġ= Ġ 5 6 . dp Ċ private Ġval ĠBottom Nav Label Transform Origin Ġ= ĠTransform Origin ( 0 f , Ġ 0 . 5 f ) Ċ private Ġval ĠBottom Nav Indicator Shape Ġ= ĠRo unded Corner Shape ( percent Ġ= Ġ 5 0 ) Ċ private Ġval ĠBottom Navigation Item Padding Ġ= ĠModifier . padding ( horizontal Ġ= Ġ 1 6 . dp , Ġvertical Ġ= Ġ 8 . dp ) Ċ Ċ // ĠBottom ĠNavigation Ċ @ Composable Ċ fun ĠPlay Bottom Nav ( ĊĠ Ġnav Controller : ĠNav Host Controller , ĊĠ Ġtabs : ĠArray < Bottom Nav Tabs >, ĊĠ Ġon Tab Selected : Ġ( String , ĠString ) Ġ-> ĠUnit , ĊĠ Ġcolor : ĠColor Ġ= ĠPlay Theme . colors . icon Primary , ĊĠ Ġcontent Color : ĠColor Ġ= ĠPlay Theme . colors . icon Interactive Ċ ) Ġ{ ĊĠ Ġval Ġnav Back Stack Entry Ġby Ġnav Controller . current Back Stack Entry As State () ĊĠ Ġval Ġcurrent Route Ġ= Ġnav Back Stack Entry ?. destination ?. route Ġ?: ĠBottom Nav Tabs . Games . route ĊĠ Ġval Ġroutes Ġ= Ġremember Ġ{ ĠBottom Nav Tabs . values (). map Ġ{ Ġit . route Ġ} Ġ} ĊĊĠ ĠPlay Surface ( ĊĠĠĠ Ġcolor Ġ= Ġcolor , ĊĠĠĠ Ġcontent Color Ġ= Ġcontent Color ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġval Ġspring Spec Ġ= Ġremember Ġ{ Ġget Anim Spec () Ġ} ĊĠĠĠ Ġif Ġ( current Route Ġin Ġroutes ) Ġ{ ĊĠĠĠĠĠ ĠColumn Ġ{ ĊĠĠĠĠĠĠĠ ĠPlay Bottom Nav Layout ( ĊĠĠĠĠĠĠĠĠĠ Ġselected Index Ġ= Ġroutes . indexOf ( current Route ), ĊĠĠĠĠĠĠĠĠĠ Ġitem Count Ġ= Ġtabs . size , ĊĠĠĠĠĠĠĠĠĠ Ġindicator Ġ= Ġ{ ĠP Lay Bottom Nav Indicator () Ġ}, ĊĠĠĠĠĠĠĠĠĠ Ġanim Spec Ġ= Ġspring Spec , ĊĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier . navigation Bars Padding ( left Ġ= Ġfalse , Ġright Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġtabs . forEach Ġ{ Ġtab Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġselected Ġ= Ġcurrent Route Ġ== Ġtab . route ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt int Ġby Ġget Bottom Nav Tint State ( selected Ġ= Ġselected ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠPlay Bottom Navigation Item ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġicon Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIcon ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimage Vector Ġ= Ġtab . icon , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt int Ġ= Ġt int , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Description Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtext Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠText ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtext Ġ= Ġstring Resource ( tab . title ). toUpperCase ( Locale . ROOT ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcolor Ġ= Ġt int , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstyle Ġ= ĠMaterial Theme . typography . button , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmax Lines Ġ= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġselected Ġ= Ġselected , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Selected Ġ= Ġ{ Ġon Tab Selected ( tab . route , Ġcurrent Route ) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġanim Spec Ġ= Ġspring Spec , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠBottom Navigation Item Padding ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. clip ( Bottom Nav Indicator Shape ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ // ĠBottom ĠNavigation ĠItem Ċ @ Composable Ċ fun ĠPlay Bottom Navigation Item ( ĊĠ Ġicon : Ġ@ Composable ĠBox Scope . () Ġ-> ĠUnit , ĊĠ Ġtext : Ġ@ Composable ĠBox Scope . () Ġ-> ĠUnit , ĊĠ Ġselected : ĠBoolean , ĊĠ Ġon Selected : Ġ() Ġ-> ĠUnit , ĊĠ Ġanim Spec : ĠAnimation Spec < Float >, ĊĠ Ġmodifier : ĠModifier Ġ= ĠModifier Ċ ) Ġ{ ĊĠ ĠBox ( ĊĠĠĠ Ġmodifier Ġ= Ġmodifier . selectable ( selected Ġ= Ġselected , ĠonClick Ġ= Ġon Selected ), ĊĠĠĠ Ġcontent Alignment Ġ= ĠAlignment . Center ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġ// ĠAn imate Ġthe Ġicon / text Ġpositions Ġwithin Ġthe Ġitem Ġbased Ġon Ġselection ĊĠĠĠ Ġval Ġanimation Progress Ġby Ġget Progress State ( selected Ġ= Ġselected , Ġanim Spec Ġ= Ġanim Spec ) ĊĠĠĠ ĠPlay Bottom Nav Item Layout ( ĊĠĠĠĠĠ Ġicon Ġ= Ġicon , ĊĠĠĠĠĠ Ġtext Ġ= Ġtext , ĊĠĠĠĠĠ Ġanimation Progress Ġ= Ġanimation Progress ĊĠĠĠ Ġ) ĊĠ Ġ} Ċ } Ċ Ċ // ĠBottom ĠNavigation ĠItem ĠLayout Ċ @ Composable Ċ private Ġfun ĠPlay Bottom Nav Item Layout ( ĊĠ Ġicon : Ġ@ Composable ĠBox Scope . () Ġ-> ĠUnit , ĊĠ Ġtext : Ġ@ Composable ĠBox Scope . () Ġ-> ĠUnit , ĊĠ Ġ@ Float Range ( from Ġ= Ġ 0 . 0 , Ġto Ġ= Ġ 1 . 0 ) Ġanimation Progress : ĠFloat Ċ ) Ġ{ ĊĠ ĠLayout ( ĊĠĠĠ Ġcontent Ġ= Ġ{ ĊĠĠĠĠĠ ĠBox ( Modifier . layout Id (" icon "), Ġcontent Ġ= Ġicon ) ĊĠĠĠĠĠ Ġval Ġscale Ġ= Ġl erp ( start Ġ= Ġ 0 . 2 f , Ġstop Ġ= Ġ 1 f , Ġfraction Ġ= Ġanimation Progress ) ĊĠĠĠĠĠ ĠBox ( ĊĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier ĊĠĠĠĠĠĠĠĠĠ Ġ. padding ( start Ġ= ĠText Icon Spacing ) ĊĠĠĠĠĠĠĠĠĠ Ġ. layout Id (" text ") ĊĠĠĠĠĠĠĠĠĠ Ġ. graphics Layer Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġalpha Ġ= Ġanimation Progress ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscale X Ġ= Ġscale ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscale Y Ġ= Ġscale ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransform Origin Ġ= ĠBottom Nav Label Transform Origin ĊĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠ Ġcontent Ġ= Ġtext ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠ Ġ) Ġ{ Ġmeas ur able , Ġconstraints Ġ-> ĊĠĠĠ Ġval Ġicon Place able Ġ= Ġmeas ur able . first Ġ{ Ġit . layout Id Ġ== Ġ" icon " Ġ} ĊĠĠĠĠĠ Ġ. measure ( constraints ) ĊĠĠĠ Ġval Ġtext Place able Ġ= Ġmeas ur able . first Ġ{ Ġit . layout Id Ġ== Ġ" text " Ġ} ĊĠĠĠĠĠ Ġ. measure ( constraints ) ĊĊĠĠĠ Ġplace Text And Icon ( ĊĠĠĠĠĠ Ġtext Place able , ĊĠĠĠĠĠ Ġicon Place able , ĊĠĠĠĠĠ Ġconstraints . maxWidth , ĊĠĠĠĠĠ Ġconstraints . max Height , ĊĠĠĠĠĠ Ġanimation Progress ĊĠĠĠ Ġ) ĊĠ Ġ} Ċ } Ċ Ċ // ĠPlace Ġtext Ġand Ġicon Ġusing ĠPlace able Ċ private Ġfun ĠMeasure Scope . place Text And Icon ( ĊĠ Ġtext Place able : ĠPlace able , ĊĠ Ġicon Place able : ĠPlace able , ĊĠ Ġwidth : ĠInt , ĊĠ Ġheight : ĠInt , ĊĠ Ġ@ Float Range ( from Ġ= Ġ 0 . 0 , Ġto Ġ= Ġ 1 . 0 ) Ġanimation Progress : ĠFloat Ċ ): ĠMeasure Result Ġ{ ĊĠ Ġval Ġicon Y Ġ= Ġ( height Ġ- Ġicon Place able . height ) Ġ/ Ġ 2 ĊĠ Ġval Ġtext Y Ġ= Ġ( height Ġ- Ġtext Place able . height ) Ġ/ Ġ 2 ĊĊĠ Ġval Ġtext Width Ġ= Ġtext Place able . width Ġ* Ġanimation Progress ĊĠ Ġval Ġicon X Ġ= Ġ( width Ġ- Ġtext Width Ġ- Ġicon Place able . width ) Ġ/ Ġ 2 ĊĠ Ġval Ġtext X Ġ= Ġicon X Ġ+ Ġicon Place able . width ĊĊĠ Ġreturn Ġlayout ( width , Ġheight ) Ġ{ ĊĠĠĠ Ġicon Place able . place ( icon X . toInt (), Ġicon Y ) ĊĠĠĠ Ġif Ġ( animation Progress Ġ!= Ġ 0 f ) Ġ{ ĊĠĠĠĠĠ Ġtext Place able . place ( text X . toInt (), Ġtext Y ) ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ // ĠBottom ĠNavigation ĠLayout Ċ @ Composable Ċ private Ġfun ĠPlay Bottom Nav Layout ( ĊĠ Ġselected Index : ĠInt , ĊĠ Ġitem Count : ĠInt , ĊĠ Ġanim Spec : ĠAnimation Spec < Float >, ĊĠ Ġindicator : Ġ@ Composable ĠBox Scope . () Ġ-> ĠUnit , ĊĠ Ġmodifier : ĠModifier Ġ= ĠModifier , ĊĠ Ġcontent : Ġ@ Composable Ġ() Ġ-> ĠUnit Ċ ) Ġ{ ĊĠ Ġ// ĠTrack Ġhow Ġ" selected " Ġeach Ġitem Ġis Ġ[ 0 , Ġ 1 ] ĊĠ Ġval Ġselection Fr actions Ġ= Ġremember ( item Count ) Ġ{ ĊĠĠĠ ĠList ( item Count ) Ġ{ Ġi Ġ-> ĊĠĠĠĠĠ ĠAnim atable ( if Ġ( i Ġ== Ġselected Index ) Ġ 1 f Ġelse Ġ 0 f ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġselection Fr actions . forEach Indexed Ġ{ Ġindex , Ġselection Fraction Ġ-> ĊĠĠĠ Ġval Ġtarget Ġ= Ġif Ġ( index Ġ== Ġselected Index ) Ġ 1 f Ġelse Ġ 0 f ĊĠĠĠ ĠLa unched Effect ( target , Ġanim Spec ) Ġ{ ĊĠĠĠĠĠ Ġselection Fraction . animate To ( target , Ġanim Spec ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ// ĠAn imate Ġthe Ġposition Ġof Ġthe Ġindicator ĊĠ Ġval Ġindicator Index Ġ= Ġremember Ġ{ ĠAnim atable ( 0 f ) Ġ} ĊĠ Ġval Ġtarget Indicator Index Ġ= Ġselected Index . toFloat () ĊĠ ĠLa unched Effect ( target Indicator Index ) Ġ{ ĊĠĠĠ Ġindicator Index . animate To ( target Indicator Index , Ġanim Spec ) ĊĠ Ġ} ĊĊĠ ĠLayout ( ĊĠĠĠ Ġmodifier Ġ= Ġmodifier . height ( Bottom Nav Height ), ĊĠĠĠ Ġcontent Ġ= Ġ{ ĊĠĠĠĠĠ Ġcontent () ĊĠĠĠĠĠ ĠBox ( Modifier . layout Id (" indicator "), Ġcontent Ġ= Ġindicator ) ĊĠĠĠ Ġ} ĊĠ Ġ) Ġ{ Ġmeas ur able , Ġconstraints Ġ-> ĊĠĠĠ Ġcheck ( item Count Ġ== Ġ( meas ur able . size Ġ- Ġ 1 )) Ġ// Ġaccount Ġfor Ġindicator ĊĊĠĠĠ Ġ// ĠDiv ide Ġthe Ġwidth Ġinto Ġn Ġ+ Ġ 1 Ġslots Ġand Ġgive Ġthe Ġselected Ġitem Ġ 2 Ġslots ĊĠĠĠ Ġval Ġun selected Width Ġ= Ġconstraints . maxWidth Ġ/ Ġ( item Count Ġ+ Ġ 1 ) ĊĠĠĠ Ġval Ġselected Width Ġ= Ġconstraints . maxWidth Ġ- Ġ( item Count Ġ- Ġ 1 ) Ġ* Ġun selected Width ĊĠĠĠ Ġval Ġindicator Meas ur able Ġ= Ġmeas ur able . first Ġ{ Ġit . layout Id Ġ== Ġ" indicator " Ġ} ĊĊĠĠĠ Ġval Ġitem Place able Ġ= Ġmeas ur able ĊĠĠĠĠĠ Ġ. filter Not Ġ{ Ġit Ġ== Ġindicator Meas ur able Ġ} ĊĠĠĠĠĠ Ġ. map Indexed Ġ{ Ġindex , Ġmeas ur ables Ġ-> ĊĠĠĠĠĠĠĠ Ġ// ĠAn imate Ġitem 's Ġwidth Ġbased Ġupon Ġthe Ġselection Ġamount ĊĠĠĠĠĠĠĠ Ġval Ġwidth Ġ= Ġl erp ( un selected Width , Ġselected Width , Ġselection Fr actions [ index ]. value ) ĊĠĠĠĠĠĠĠ Ġmeas ur ables . measure ( ĊĠĠĠĠĠĠĠĠĠ Ġconstraints . copy ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠminWidth Ġ= Ġwidth , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠmaxWidth Ġ= Ġwidth ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġindicator Place able Ġ= Ġindicator Meas ur able . measure ( ĊĠĠĠĠĠ Ġconstraints . copy ( ĊĠĠĠĠĠĠĠ ĠminWidth Ġ= Ġselected Width , ĊĠĠĠĠĠĠĠ ĠmaxWidth Ġ= Ġselected Width ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġlayout ( ĊĠĠĠĠĠ Ġwidth Ġ= Ġconstraints . maxWidth , ĊĠĠĠĠĠ Ġheight Ġ= Ġitem Place able . max By OrNull Ġ{ Ġit . height Ġ} ?. height Ġ?: Ġ 0 ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠ Ġval Ġindicator Left Ġ= Ġindicator Index . value Ġ* Ġun selected Width ĊĠĠĠĠĠ Ġindicator Place able . place ( x Ġ= Ġindicator Left . toInt (), Ġy Ġ= Ġ 0 ) ĊĠĠĠĠĠ Ġvar Ġx Ġ= Ġ 0 ĊĠĠĠĠĠ Ġitem Place able . forEach Ġ{ Ġplace able Ġ-> ĊĠĠĠĠĠĠĠ Ġplace able . place ( x Ġ= Ġx , Ġy Ġ= Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġx Ġ+= Ġplace able . width ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ // ĠBottom ĠNavigation ĠIndicator Ċ @ Composable Ċ private Ġfun ĠP Lay Bottom Nav Indicator ( ĊĠ ĠstrokeWidth : ĠD p Ġ= Ġ 1 . dp , ĊĠ Ġcolor : ĠColor Ġ= ĠPlay Theme . colors . icon Interactive , ĊĠ Ġshape : ĠShape Ġ= ĠBottom Nav Indicator Shape Ċ ) Ġ{ ĊĠ ĠSp acer ( ĊĠĠĠ Ġmodifier Ġ= ĠModifier ĊĠĠĠĠĠ Ġ. fill MaxSize () ĊĠĠĠĠĠ Ġ. then ( Bottom Navigation Item Padding ) ĊĠĠĠĠĠ Ġ. border ( stroke Width , Ġcolor , Ġshape ) ĊĠ Ġ) Ċ } Ċ Ċ private Ġfun Ġget Anim Spec (): ĠSpring Spec < Float > Ġ{ ĊĠ Ġreturn ĠSpring Spec ( ĊĠĠĠ Ġ// ĠDetermin ed Ġexperiment ally ĊĠĠĠ Ġst iff ness Ġ= Ġ 2 0 0 f , ĊĠĠĠ Ġd amping Ratio Ġ= Ġ 0 . 9 f ĊĠ Ġ) Ċ }