package Ġcom . shim . recycler . recycler list Ċ Ċ import Ġandroid . util . Log Ċ import Ġkotlin . math . abs Ċ import Ġkotlin . math . ceil Ċ import Ġkotlin . math . round ToInt Ċ Ċ class ĠGrid Optimize Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġglobal Scroll Position Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠ Ġvar Ġglobal _ scroll _ velocity Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMIN _ ST ABLE _ SCROLL _ VE LOC ITY _ FOR _ PE AK Ġ= Ġ 2 f ĊĊĠĠĠĠĠĠĠ Ġfun Ġrun Scroll ( opt Object : ĠGrid Optimization Object , Ġis Horizontal : ĠBoolean Ġ= Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( opt Object . view Group . child Count Ġ== Ġ 0 ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfirst Child Ġ= Ġopt Object . view Group . getChild At ( 0 ) Ġ?: Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( firstChild . meas ured Height Ġ== Ġ 0 Ġ&& Ġ! is Horizontal ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( firstChild . meas ured Width Ġ== Ġ 0 Ġ&& Ġis Horizontal ) Ġreturn ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* Ui Utils . debug Coords ( firstChild ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" Grid ĠLayout ", Ġ" G RR II ID DD LAYOUT ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUi Utils . debug Coords ( view Group ) */ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . view Group . getGlobal Visible Rect ( opt Object . container _ visible _ rect f ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfirst Child . getLocation On Screen ( opt Object . first _ child _ location _ on _ screen ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . view Group . getLocation On Screen ( opt Object . container _ location _ on _ screen ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtop _ of _ container Ġ= Ġif Ġ(! is Horizontal ) Ġopt Object . container _ visible _ rect f . top Ġelse Ġopt Object . container _ visible _ rect f . left ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġy _ of _ first Ġ= Ġif Ġ(! is Horizontal ) Ġopt Object . first _ child _ location _ on _ screen [ 1 ] Ġelse Ġopt Object . first _ child _ location _ on _ screen [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġview _ height Ġ= Ġif Ġ(! is Horizontal ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . container _ visible _ rect f . bottom Ġ- Ġopt Object . container _ visible _ rect f . top ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . container _ visible _ rect f . right Ġ- Ġopt Object . container _ visible _ rect f . left ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġabs _ visible _ center Ġ= Ġview _ height Ġ/ Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġabs _ visible _ peak Ġ= Ġ( view _ height Ġ* Ġ( 1 f Ġ- Ġopt Object . opt Handler . normalized Peak Height )). toInt () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( top _ of _ container Ġ- Ġy _ of _ first Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġy _ of _ first _ dp Ġ= ĠUtils . dp From Px ( opt Object . view Group . context , Ġy _ of _ first . toFloat ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġglobal _ scroll _ velocity Ġ= Ġabs ( global Scroll Position Ġ- Ġy _ of _ first _ dp ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Error Log . e ( Emoji Tags . App , Ġ" Scroll ĠVe locity : Ġ$ global _ scroll _ velocity ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġglobal Scroll Position Ġ= Ġy _ of _ first _ dp ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Is Ġthere Ġvariance Ġin Ġcells ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsingular View D iment ion Ġ= Ġ( if Ġ(! is Horizontal ) Ġfirst Child . meas ured Height Ġelse Ġfirst Child . meas ured Width ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Variable Cell Type Ġ= Ġopt Object . opt Handler . cells . size Ġ> Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtotal _ height _ till _ bottom Ġ= Ġ(( top _ of _ container Ġ+ Ġview _ height ) Ġ- Ġy _ of _ first ) ĊĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠstartTime Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew _ bottom _ row _ visible Ġ= Ġif Ġ( is Variable Cell Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġheight So Far Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcell Index Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( height So Far Ġ< Ġtotal _ height _ till _ bottom ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġheight So Far Ġ+= Ġopt Object . opt Handler . getCell Height ( cell Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcell Index ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcell Index Ġ- Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtotal _ height _ till _ bottom Ġ/ Ġsingular View D iment ion ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnew _ top _ row _ visible Ġ= Ġif Ġ( is Variable Cell Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġheight So Far Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcell Index Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( height So Far Ġ< Ġtotal _ height _ till _ bottom Ġ- Ġview _ height ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġheight So Far Ġ+= Ġopt Object . opt Handler . getCell Height ( cell Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcell Index ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcell Index Ġ- Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġno _ of _ rows _ on _ screen Ġ= Ġceil ( view _ height . toFloat () Ġ/ Ġsingular View D iment ion . toFloat ()). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew _ bottom _ row _ visible Ġ- Ġno _ of _ rows _ on _ screen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbottom _ row _ for _ peak Ġ= Ġif Ġ( is Variable Cell Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġheight So Far Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcell Index Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( height So Far Ġ< Ġ( total _ height _ till _ bottom Ġ+ Ġview _ height Ġ* Ġopt Object . opt Handler . normalized Peak Height )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġheight So Far Ġ+= Ġopt Object . opt Handler . getCell Height ( cell Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcell Index ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( cell Index Ġ- Ġ 1 ). toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( total _ height _ till _ bottom Ġ+ Ġview _ height Ġ* Ġopt Object . opt Handler . normalized Peak Height ) Ġ/ Ġsingular View D iment ion ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew _ middle _ row _ visible Ġ= Ġif Ġ( is Variable Cell Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġheight So Far Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcell Index Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( height So Far Ġ< Ġtotal _ height _ till _ bottom Ġ- Ġview _ height Ġ/ Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġheight So Far Ġ+= Ġopt Object . opt Handler . getCell Height ( cell Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcell Index ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcell Index Ġ- Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ(( new _ top _ row _ visible Ġ+ Ġbottom _ row _ for _ peak ) Ġ/ Ġ 2 . 0 f ). round ToInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Log . e ( Emoji Tags . App , Ġ" Perf : Ġ${ System . currentTimeMillis () Ġ- ĠstartTime }") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( new _ top _ row _ visible Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew _ top _ row _ visible Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Stable ĠPe ak Ġrow ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( global _ scroll _ velocity Ġ< ĠMIN _ ST ABLE _ SCROLL _ VE LOC ITY _ FOR _ PE AK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( new _ middle _ row _ visible Ġ!= Ġopt Object . middle _ row _ visible ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( 0 Ġuntil Ġopt Object . numberOf Columns ). forEach Ġ{ ĠcolumnIndex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġnew _ middle _ row _ visible Ġ* Ġopt Object . numberOf Columns Ġ+ ĠcolumnIndex ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . opt Handler . on Stable View Peak ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . middle _ row _ visible Ġ= Ġnew _ middle _ row _ visible ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( new _ top _ row _ visible Ġ!= Ġopt Object . top _ row _ visible Ġ|| Ġnew _ bottom _ row _ visible Ġ!= Ġopt Object . bottom _ row _ visible ) Ġ{ ĊĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Add Ġvisible Ġindex ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( opt Object . top _ row _ visible .. opt Object . bottom _ row _ visible ). forEach Ġ{ Ġrow Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( row Ġ< Ġnew _ top _ row _ visible Ġ|| Ġrow Ġ> Ġnew _ bottom _ row _ visible ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( 0 Ġuntil Ġopt Object . numberOf Columns ). forEach Ġ{ ĠcolumnIndex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġrow Ġ* Ġopt Object . numberOf Columns Ġ+ ĠcolumnIndex ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( opt Object . opt Handler . visible _ cells . contains ( key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . opt Handler . visible _ cells . remove ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// On ĠAdded ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . opt Handler . on View Not Visible ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . top _ row _ visible Ġ= Ġnew _ top _ row _ visible ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . bottom _ row _ visible Ġ= Ġnew _ bottom _ row _ visible ĊĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Add Ġvisible Ġindex ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( opt Object . top _ row _ visible .. opt Object . bottom _ row _ visible ). forEach Ġ{ Ġrow Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( 0 Ġuntil Ġopt Object . numberOf Columns ). forEach Ġ{ ĠcolumnIndex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġrow Ġ* Ġopt Object . numberOf Columns Ġ+ ĠcolumnIndex ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! opt Object . opt Handler . visible _ cells . contains ( key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . opt Handler . visible _ cells . add ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// On ĠAdded ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . opt Handler . on View Visible ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( false ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" ---- ", Ġ" -------------------------------- ----- ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" top _ of _ container ĠĠĠĠ Ġ", Ġtop _ of _ container . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" y _ of _ first ĠĠĠĠĠĠĠĠĠĠ Ġ", Ġy _ of _ first . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" abs _ visible _ center ĠĠ Ġ", Ġabs _ visible _ center . toString ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" Top ĠRow ĠVis ible ĠĠĠĠĠĠ Ġ: ", Ġ" Ġ" Ġ+ Ġopt Object . top _ row _ visible . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" Middle ĠRow ĠVis ible ĠĠĠ Ġ: ", Ġ" Ġ" Ġ+ Ġopt Object . middle _ row _ visible . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" Bottom ĠRow ĠVis ible ĠĠĠ Ġ: ", Ġ" Ġ" Ġ+ Ġopt Object . bottom _ row _ visible . toString ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġindex SetString Ġ= Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopt Object . opt Handler . visible _ cells . forEach Ġ{ Ġkey : ĠInt Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindex SetString Ġ+= Ġ"$ key , Ġ" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" Index ĠSet ĠĠĠĠĠĠĠĠĠĠĠĠ Ġ: ", Ġindex SetString ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }