package Ġio . ak 1 . pix . helpers Ċ Ċ import Ġandroid . animation . Animator Ċ import Ġandroid . animation . Animator Listener Adapter Ċ import Ġandroid . content . Context Ċ import Ġandroid . os . Handler Ċ import Ġandroid . os . Looper Ċ import Ġandroid . view . View Ċ import Ġandroid . view . View Property Animator Ċ import Ġandroidx . core . view . isVisible Ċ import Ġandroidx . recyclerview . widget . RecyclerView Ċ import Ġio . ak 1 . pix . Pix Fragment Ċ import Ġio . ak 1 . pix . R Ċ import Ġio . ak 1 . pix . databinding . Fragment Pix Binding Ċ import Ġio . ak 1 . pix . utility . s Scrollbar Anim Duration Ċ import Ġkotlin . math . max Ċ import Ġkotlin . math . min Ċ import Ġkotlin . math . round ToInt Ċ Ċ /** Ċ Ġ* ĠCreated ĠBy ĠAk sh ay ĠSh arma Ġon Ġ 1 7 , June , 2 0 2 1 Ċ Ġ* Ġhttps :// ak 1 . io Ċ Ġ*/ ĊĊ Ċ // Video ĠCounter ĠHandler Ġand ĠRunnable Ċ internal Ġval Ġhandler Ġ= ĠHandler ( Looper . get Main Looper ()) Ċ internal Ġvar Ġm Scrollbar Animator : ĠView Property Animator ? Ġ= Ġnull Ċ internal Ġvar Ġm Bubble Animator : ĠView Property Animator ? Ġ= Ġnull Ċ internal Ġvar Ġm View Height Ġ= Ġ 0 f Ċ internal Ġconst Ġval Ġm Hide Scrollbar Ġ= Ġtrue Ċ internal Ġconst Ġval Ġs Bubble Anim Duration Ġ= Ġ 1 0 0 0 Ċ internal Ġconst Ġval Ġs Scrollbar Hide Delay Ġ= Ġ 1 0 0 0 Ċ internal Ġconst Ġval Ġs Track Snap Range Ġ= Ġ 5 Ċ internal Ġvar Ġtoolbar Height Ġ= Ġ 0 f Ċ Ċ fun Ġcancel Animation ( var arg Ġanim ator : ĠView Property Animator ?) Ġ{ ĊĠĠĠ Ġanim ator . forEach Ġ{ ĊĠĠĠĠĠĠĠ Ġit ?. cancel () ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġshow Scrollbar ( m Scrollbar : ĠView ?, Ġcontext : ĠContext ): ĠView Property Animator Ġ{ ĊĠĠĠ Ġval Ġtrans X Ġ= Ġcontext . resources . get Dimension Pixel Size ( R . dim en . fast scroll _ bubble _ size ). toFloat () ĊĠĠĠ Ġm Scrollbar !!. translation X Ġ= Ġtrans X ĊĠĠĠ Ġm Scrollbar . visibility Ġ= ĠView . VISIBLE ĊĠĠĠ Ġreturn Ġm Scrollbar . animate (). translation X ( 0 f ). alpha ( 1 f ) ĊĠĠĠĠĠĠĠ Ġ. set Duration ( s Scrollbar Anim Duration . to Long ()) ĊĠĠĠĠĠĠĠ Ġ. set Listener ( object Ġ: ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAn imator Listener Adapter () Ġ{ Ġ// Ġadapter Ġrequired Ġfor Ġnew Ġalpha Ġvalue Ġto Ġstick ĊĠĠĠĠĠĠĠ Ġ}) Ċ } Ċ Ċ fun ĠgetValue InRange ( min : ĠInt , Ġmax : ĠInt , Ġvalue : ĠInt ): ĠInt Ġ{ ĊĠĠĠ Ġval Ġminimum Ġ= Ġmax ( min , Ġvalue ) ĊĠĠĠ Ġreturn Ġmin ( minimum , Ġmax ) Ċ } Ċ Ċ internal Ġfun ĠFragment Pix Binding . setView Positions ( y : ĠFloat ) Ġ{ ĊĠĠĠ Ġval Ġhandle Y : ĠInt Ġ= ĠgetValue InRange ( ĊĠĠĠĠĠĠĠĠ 0 , Ġ( m View Height Ġ- Ġgrid Layout . fast scroll Handle . height ). toInt (), ĊĠĠĠĠĠĠĠ Ġ( y Ġ- Ġgrid Layout . fast scroll Handle . height Ġ/ Ġ 2 ). toInt () ĊĠĠĠ Ġ) ĊĠĠĠ Ġgrid Layout . fast scroll Bubble . y Ġ= Ġhandle Y Ġ+ Ġroot . context . to Px ( 6 0 f ) ĊĠĠĠ Ġgrid Layout . fast scroll Handle . y Ġ= Ġhandle Y . toFloat () Ċ } ĊĊ Ċ fun ĠFragment Pix Binding . hide Scrollbar () Ġ{ ĊĠĠĠ Ġ// val Ġtrans X Ġ= Ġresources . get Dimension Pixel Size ( R . dim en . fast scroll _ scrollbar _ padding _ end ). toFloat () ĊĠĠĠ Ġm Scrollbar Animator Ġ= ĊĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Scrollbar . animate (). translation X ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Scrollbar . width . toFloat () ĊĠĠĠĠĠĠĠ Ġ). alpha ( 0 f ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Duration ( s Scrollbar Anim Duration . to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Listener ( object Ġ: ĠAn imator Listener Adapter () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation End ( animation : ĠAn imator ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Animation End ( animation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Scrollbar . hide () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Scrollbar Animator Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Cancel ( animation : ĠAn imator ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Animation Cancel ( animation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Scrollbar . hide () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Scrollbar Animator Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) Ċ } ĊĊ Ċ fun Ġscroll Listener ( ĊĠĠĠ Ġfragment : ĠP ix Fragment , ĊĠĠĠ Ġbinding : ĠFragment Pix Binding Ċ ): ĠRecyclerView . On Scroll Listener Ġ= ĊĠĠĠ Ġobject Ġ: ĠRecyclerView . On Scroll Listener () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Sc rolled ( re cyclerView : ĠRecyclerView , Ġdx : ĠInt , Ġdy : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! binding . grid Layout . fast scroll Handle . isSelected Ġ&& Ġre cyclerView . isEnabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . setView Positions ( get Scroll Pro portion ( re cyclerView )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Scroll StateChanged ( re cyclerView : ĠRecyclerView , ĠnewState : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Scroll StateChanged ( re cyclerView , ĠnewState ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( re cyclerView . isEnabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( newState ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRecyclerView . SCROLL _ STATE _ DR AG GING Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . remove Callbacks ( fragment . m Scrollbar H ider ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( binding . grid Layout . fast scroll Scrollbar . visibility Ġ!= ĠView . VISIBLE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcancel Animation ( m Scrollbar Animator ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! binding . grid Layout . fast scroll Scrollbar . isVisible Ġ&& Ġ( re cyclerView . compute Vertical Scroll Range () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ- Ġm View Height Ġ> Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Scrollbar Animator Ġ= Ġshow Scrollbar ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . grid Layout . fast scroll Scrollbar , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . grid Layout . fast scroll Scrollbar . context ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRecyclerView . SCROLL _ STATE _ IDLE Ġ-> Ġif Ġ( m Hide Scrollbar Ġ&& Ġ! binding . grid Layout . fast scroll Handle . isSelected ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . post Delayed ( fragment . m Scrollbar H ider , Ġs Scrollbar Hide Delay . to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ fun Ġget Scroll Pro portion ( re cyclerView : ĠRecyclerView ?): ĠFloat Ġ{ ĊĠĠĠ Ġval Ġvertical Scroll Offset Ġ= Ġre cyclerView !!. compute Vertical Scroll Offset () ĊĠĠĠ Ġval Ġvertical Scroll Range Ġ= Ġre cyclerView . compute Vertical Scroll Range () ĊĠĠĠ Ġval Ġrange Diff Ġ= Ġvertical Scroll Range Ġ- Ġm View Height ĊĠĠĠ Ġval Ġproportion Ġ= Ġvertical Scroll Offset . toFloat () Ġ/ Ġif Ġ( range Diff Ġ> Ġ 0 ) Ġrange Diff Ġelse Ġ 1 f ĊĠĠĠ Ġreturn Ġm View Height Ġ* Ġproportion Ċ } Ċ Ċ fun ĠFragment Pix Binding . hide Bubble () Ġ{ ĊĠĠĠ Ġif Ġ( grid Layout . fast scroll Bubble . isVisible ) Ġ{ ĊĠĠĠĠĠĠĠ Ġm Bubble Animator Ġ= Ġgrid Layout . fast scroll Bubble . animate (). alpha ( 0 f ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Duration ( s Bubble Anim Duration . to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Listener ( object Ġ: ĠAn imator Listener Adapter () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation End ( animation : ĠAn imator ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Animation End ( animation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Bubble . hide () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Bubble Animator Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Cancel ( animation : ĠAn imator ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Animation Cancel ( animation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Bubble . hide () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Bubble Animator Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġm Bubble Animator !!. start () ĊĠĠĠ Ġ} Ċ } ĊĊ Ċ fun ĠFragment Pix Binding . set RecyclerView Position ( y : ĠFloat ) Ġ{ ĊĠĠĠ Ġif Ġ( grid Layout . re cyclerView . adapter Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġitem Count Ġ= Ġgrid Layout . re cyclerView . adapter !!. item Count ĊĠĠĠĠĠĠĠ Ġval Ġproportion : ĠFloat Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Handle . y Ġ== Ġ 0 f Ġ-> Ġ 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Handle . y Ġ+ Ġgrid Layout . fast scroll Handle . height Ġ>= Ġm View Height Ġ- Ġs Track Snap Range Ġ-> Ġ 1 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġy Ġ/ Ġm View Height ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġsc rolled ItemCount Ġ= Ġ( pro portion Ġ* Ġitem Count ). round ToInt () ĊĠĠĠĠĠĠĠ Ġval Ġtarget Pos : ĠInt Ġ= ĠgetValue InRange ( 0 , Ġitem Count Ġ- Ġ 1 , Ġsc rolled ItemCount ) ĊĠĠĠĠĠĠĠ Ġgrid Layout . re cyclerView . layout Manager !!. scrollTo Position ( target Pos ) ĊĠĠĠĠĠĠĠ Ġval Ġtext Ġ= Ġmain Image Adapter . get Section Month Year Text ( target Pos ) ĊĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Bubble . text Ġ= Ġtext ĊĠĠĠĠĠĠĠ Ġif Ġ( text . equals ("", Ġignore Case Ġ= Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Bubble . hide () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠFragment Pix Binding . show Bubble () Ġ{ ĊĠĠĠ Ġif Ġ(! grid Layout . fast scroll Bubble . isVisible ) Ġ{ ĊĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Bubble . show () ĊĠĠĠĠĠĠĠ Ġgrid Layout . fast scroll Bubble . alpha Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠ Ġm Bubble Animator Ġ= Ġgrid Layout . fast scroll Bubble ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. animate () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. alpha ( 1 f ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Duration ( s Bubble Anim Duration . to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Listener ( object Ġ: ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAn imator Listener Adapter () Ġ{ Ġ// Ġadapter Ġrequired Ġfor Ġnew Ġalpha Ġvalue Ġto Ġstick ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġm Bubble Animator !!. start () ĊĠĠĠ Ġ} Ċ } Ċ