package Ġcom . ig reen wood . lo upe Ċ Ċ import Ġandroid . animation . Animator Ċ import Ġandroid . animation . Value Animator Ċ import Ġandroid . graphics . Matrix Ċ import Ġandroid . graphics . PointF Ċ import Ġandroid . graphics . Rect Ċ import Ġandroid . graphics . Rect F Ċ import Ġandroid . graphics . drawable . Bitmap Drawable Ċ import Ġandroid . util . Typed Value Ċ import Ġandroid . view . Gesture Detector Ċ import Ġandroid . view . Motion Event Ċ import Ġandroid . view . Scale Gesture Detector Ċ import Ġandroid . view . View Ċ import Ġandroid . view . ViewGroup Ċ import Ġandroid . view . animation . Accel erate De cel erate Interpolator Ċ import Ġandroid . view . animation . De cel erate Interpolator Ċ import Ġandroid . view . animation . Interpolator Ċ import Ġandroid . widget . ImageView Ċ import Ġandroid . widget . Over Scroller Ċ import Ġandroidx . core . view . View Compat Ċ import Ġjava . lang . ref . Weak Reference Ċ import Ġkotlin . math . abs Ċ import Ġkotlin . math . max Ċ import Ġkotlin . math . min Ċ import Ġkotlin . math . round ToInt Ċ Ċ class ĠL ou pe ( imageView : ĠImageView , Ġcontainer : ĠViewGroup ) Ġ: ĠView . On Touch Listener , ĊĠĠĠ ĠView . On Layout ChangeListener Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDEFAULT _ MAX _ ZO OM Ġ= Ġ 5 . 0 f ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDEFAULT _ ANIM _ DURATION Ġ= Ġ 2 5 0 L ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDEFAULT _ ANIM _ DURATION _ LONG Ġ= Ġ 3 7 5 L ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDEFAULT _ VIEW _ DR AG _ FR I CTION Ġ= Ġ 1 f ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDEFAULT _ DR AG _ DIS MIS S _ DISTANCE _ IN _ VIEW _ HEIGHT _ RATIO Ġ= Ġ 0 . 5 f ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDEFAULT _ DR AG _ DIS MIS S _ DISTANCE _ IN _ DP Ġ= Ġ 9 6 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠMAX _ FL ING _ VE LOC ITY Ġ= Ġ 8 0 0 0 f ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠMIN _ FL ING _ VE LOC ITY Ġ= Ġ 1 5 0 0 f ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDEFAULT _ DOUBLE _ T AP _ ZO OM _ SCALE Ġ= Ġ 0 . 5 f ĊĠĠĠĠĠĠĠ Ġval ĠDEFAULT _ INTER POL ATOR Ġ= ĠDec el erate Interpolator () ĊĊĠĠĠĠĠĠĠ Ġfun Ġcreate ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠimageView : ĠImageView , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontainer : ĠViewGroup , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconfig : ĠL ou pe . () Ġ-> ĠUnit Ġ= Ġ{ Ġ} ĊĠĠĠĠĠĠĠ Ġ): ĠL ou pe Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠL ou pe ( imageView , Ġcontainer ). apply ( config ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinterface ĠOn View Translate Listener Ġ{ ĊĠĠĠĠĠĠĠ Ġfun ĠonStart ( view : ĠImageView ) ĊĠĠĠĠĠĠĠ Ġfun Ġon View Translate ( view : ĠImageView , Ġamount : ĠFloat ) ĊĠĠĠĠĠĠĠ Ġfun Ġon Dismiss ( view : ĠImageView ) ĊĠĠĠĠĠĠĠ Ġfun Ġon Restore ( view : ĠImageView ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinterface ĠOn Scale Changed Listener Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġon Scale Change ( scale Factor : ĠFloat , Ġfocus X : ĠFloat , Ġfocus Y : ĠFloat ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinterface ĠOn View ClickListener Ġ{ ĊĠĠĠĠĠĠĠ Ġfun ĠonClick ( view : ĠImageView ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġmax Ġzoom ( > Ġ 1 f ) ĊĠĠĠ Ġvar Ġmax Zoom Ġ= ĠDEFAULT _ MAX _ ZO OM ĊĠĠĠ Ġ// Ġuse Ġfl ing Ġgesture Ġfor Ġdismiss ĊĠĠĠ Ġvar Ġuse Fl ing To Dismiss Gesture Ġ= Ġtrue ĊĠĠĠ Ġ// Ġflag Ġto Ġenable Ġor Ġdisable Ġdrag Ġto Ġdismiss ĊĠĠĠ Ġvar Ġuse Drag To Dismiss Ġ= Ġtrue ĊĠĠĠ Ġ// Ġduration Ġmillis Ġfor Ġdismiss Ġanimation ĊĠĠĠ Ġvar Ġdismiss Animation Duration Ġ= ĠDEFAULT _ ANIM _ DURATION ĊĠĠĠ Ġ// Ġduration Ġmillis Ġfor Ġrestore Ġanimation ĊĠĠĠ Ġvar Ġrestore Animation Duration Ġ= ĠDEFAULT _ ANIM _ DURATION ĊĠĠĠ Ġ// Ġduration Ġmillis Ġfor Ġimage Ġanimation ĊĠĠĠ Ġvar Ġfl ing Animation Duration Ġ= ĠDEFAULT _ ANIM _ DURATION ĊĠĠĠ Ġ// Ġduration Ġmillis Ġfor Ġdouble Ġtap Ġscale Ġanimation ĊĠĠĠ Ġvar Ġscale Animation Duration Ġ= ĠDEFAULT _ ANIM _ DURATION _ LONG ĊĠĠĠ Ġ// Ġduration Ġmillis Ġfor Ġover Ġscale Ġanimation ĊĠĠĠ Ġvar Ġover Scale Animation Duration Ġ= ĠDEFAULT _ ANIM _ DURATION _ LONG ĊĠĠĠ Ġ// Ġduration Ġmillis Ġfor Ġover Ġscrolling Ġanimation ĊĠĠĠ Ġvar Ġover Scroll Animation Duration Ġ= ĠDEFAULT _ ANIM _ DURATION ĊĠĠĠ Ġ// Ġview Ġdrag Ġf riction Ġfor Ġswipe Ġto Ġdismiss ( 1 f Ġ: Ġdrag Ġdistance Ġ== Ġview Ġmove Ġdistance . ĠSmall er Ġvalue , Ġview Ġis Ġmoving Ġmore Ġslower ) ĊĠĠĠ Ġvar Ġview Drag F riction Ġ= ĠDEFAULT _ VIEW _ DR AG _ FR I CTION ĊĠĠĠ Ġ// Ġdrag Ġdistance Ġthreshold Ġin Ġdp Ġfor Ġswipe Ġto Ġdismiss ĊĠĠĠ Ġvar Ġdrag Dismiss Distance In Dp Ġ= ĠDEFAULT _ DR AG _ DIS MIS S _ DISTANCE _ IN _ DP ĊĠĠĠ Ġ// Ġon Ġview Ġtranslate Ġlistener ĊĠĠĠ Ġvar Ġon View Translate Listener : ĠOn View Translate Listener ? Ġ= Ġnull ĊĠĠĠ Ġ// Ġon Ġscale Ġchanged ĊĠĠĠ Ġvar Ġon Scale Changed Listener : ĠOn Scale Changed Listener ? Ġ= Ġnull ĊĊĠĠĠ Ġvar Ġon View ClickListener : ĠOn View ClickListener ? Ġ= Ġnull ĊĊĠĠĠ Ġvar Ġdismiss Animation Interpolator : ĠInterpol ator Ġ= ĠDEFAULT _ INTER POL ATOR ĊĊĠĠĠ Ġvar Ġrestore Animation Interpolator : ĠInterpol ator Ġ= ĠDEFAULT _ INTER POL ATOR ĊĊĠĠĠ Ġvar Ġfl ing Animation Interpolator : ĠInterpol ator Ġ= ĠDEFAULT _ INTER POL ATOR ĊĊĠĠĠ Ġvar Ġdouble Tap Scale Animation Interpolator : ĠInterpol ator Ġ= ĠAccel erate De cel erate Interpolator () ĊĊĠĠĠ Ġvar Ġover Scale Animation Interpolator : ĠInterpol ator Ġ= ĠDEFAULT _ INTER POL ATOR ĊĊĠĠĠ Ġvar Ġover Scroll Animation Interpolator : ĠInterpol ator Ġ= ĠDEFAULT _ INTER POL ATOR ĊĊĠĠĠ Ġvar Ġdouble Tap Zoom Scale : ĠFloat Ġ= ĠDEFAULT _ DOUBLE _ T AP _ ZO OM _ SCALE Ġ// Ġ 0 f ~ 1 f ĊĊĠĠĠ Ġvar Ġminimum Fl ing Velocity : ĠFloat Ġ= ĠMIN _ FL ING _ VE LOC ITY ĊĊĠĠĠ Ġprivate Ġvar Ġfl ing Animator : ĠAn imator Ġ= ĠValue Animator () ĊĊĠĠĠ Ġ// Ġbitmap Ġmatrix ĊĠĠĠ Ġprivate Ġvar Ġtrans from Ġ= ĠMatrix () ĊĠĠĠ Ġ// Ġbitmap Ġscale ĊĠĠĠ Ġprivate Ġvar Ġscale Ġ= Ġ 1 f ĊĠĠĠ Ġ// Ġis Ġready Ġfor Ġdrawing Ġbitmap ĊĠĠĠ Ġprivate Ġvar Ġis Ready To Draw Ġ= Ġfalse ĊĠĠĠ Ġ// Ġview Ġrect Ġ- Ġpadding Ġ( re calculated Ġon Ġsize Ġchanged ) ĊĠĠĠ Ġprivate Ġvar Ġcanvas Bounds Ġ= ĠRect F () ĊĠĠĠ Ġ// Ġbitmap Ġdrawing Ġrect Ġ( move Ġon Ġscroll , Ġre calculated Ġon Ġscale Ġchanged ) ĊĠĠĠ Ġprivate Ġvar Ġbitmap Bounds Ġ= ĠRect F () ĊĠĠĠ Ġ// Ġdisplaying Ġbitmap Ġrect Ġ( does Ġnot Ġmove , Ġre calculated Ġon Ġscale Ġchanged ) ĊĠĠĠ Ġprivate Ġvar Ġviewport Ġ= ĠRect F () ĊĠĠĠ Ġ// Ġminimum Ġscale Ġof Ġbitmap ĊĠĠĠ Ġprivate Ġvar Ġmin Scale Ġ= Ġ 1 f ĊĠĠĠ Ġ// Ġmaximum Ġscale Ġof Ġbitmap ĊĠĠĠ Ġprivate Ġvar Ġmax Scale Ġ= Ġ 1 f ĊĠĠĠ Ġ// Ġbitmap Ġ( decoded ) Ġwidth ĊĠĠĠ Ġprivate Ġvar Ġimage Width Ġ= Ġ 0 f ĊĠĠĠ Ġ// Ġbitmap Ġ( decoded ) Ġheight ĊĠĠĠ Ġprivate Ġvar Ġimage Height Ġ= Ġ 0 f ĊĊĠĠĠ Ġprivate Ġval Ġsc roller : ĠOver Scroller ĊĠĠĠ Ġprivate Ġvar Ġoriginal View Bounds Ġ= ĠRect () ĊĠĠĠ Ġprivate Ġvar Ġdrag To Dismiss Threshold Ġ= Ġ 0 f ĊĠĠĠ Ġprivate Ġvar Ġdrag Dismiss Distance In Px Ġ= Ġ 0 f ĊĠĠĠ Ġprivate Ġvar Ġis View Translate Animation Running Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġis Vertical Scroll Enabled Ġ= Ġtrue ĊĠĠĠ Ġprivate Ġvar Ġis Horizontal Scroll Enabled Ġ= Ġtrue ĊĠĠĠ Ġprivate Ġvar Ġis Bitmap Translate Animation Running Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġis Bitmap Scale Animation Run nin ng Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġinitial Y Ġ= Ġ 0 f ĊĠĠĠ Ġ// Ġscaling Ġhelper ĊĠĠĠ Ġprivate Ġvar Ġscale Gesture Detector : ĠScale Gesture Detector ? Ġ= Ġnull ĊĠĠĠ Ġ// Ġtrans lating Ġhelper ĊĠĠĠ Ġprivate Ġvar Ġgesture Detector : ĠGest ure Detector ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġval Ġon Scale Gesture Listener : ĠScale Gesture Detector . On Scale Gesture Listener Ġ= ĊĠĠĠĠĠĠĠ Ġobject Ġ: ĠScale Gesture Detector . On Scale Gesture Listener Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Scale ( detector : ĠScale Gesture Detector ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Dragging () Ġ|| Ġis Bitmap Translate Animation Running Ġ|| Ġis Bitmap Scale Animation Run nin ng ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscale Factor Ġ= Ġdetector ?. scale Factor Ġ?: Ġ 1 . 0 f ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġf ocal X Ġ= Ġdetector ?. focus X Ġ?: Ġbitmap Bounds . center X () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġf ocal Y Ġ= Ġdetector ?. focus Y Ġ?: Ġbitmap Bounds . center Y () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( detector ?. scale Factor Ġ== Ġ 1 . 0 f ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġscale Ġis Ġnot Ġchanging ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġzoom To Target Scale ( calc New Scale ( scale Factor ), Ġf ocal X , Ġf ocal Y ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Scale Begin ( p 0 : ĠScale Gesture Detector ?): ĠBoolean Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Scale End ( p 0 : ĠScale Gesture Detector ?) Ġ{} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġon Gesture Listener : ĠGest ure Detector . On Gesture Listener Ġ= ĊĠĠĠĠĠĠĠ Ġobject Ġ: ĠGest ure Detector . Simple On Gesture Listener () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Down ( e : ĠMotion Event ?): ĠBoolean Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Scroll ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe 1 : ĠMotion Event ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe 2 : ĠMotion Event ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdistance X : ĠFloat , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdistance Y : ĠFloat ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( e 2 ?. pointer Count Ġ!= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scale Ġ> Ġmin Scale ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Scroll ( distance X , Ġdistance Y ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( use Drag To Dismiss Ġ&& Ġscale Ġ== Ġmin Scale ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Drag ( distance Y ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Fl ing ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe 1 : ĠMotion Event ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe 2 : ĠMotion Event ?, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvelocity X : ĠFloat , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvelocity Y : ĠFloat ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe 1 Ġ?: Ġreturn Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scale Ġ> Ġmin Scale ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Fl ing Bitmap ( velocity X , Ġvelocity Y ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Fl ing To Dismiss ( velocity Y ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Double Tap ( e : ĠMotion Event ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe Ġ?: Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Bitmap Scale Animation Run nin ng ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scale Ġ> Ġmin Scale ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġzoom Out To Minimum Scale () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġzoom In To Target Scale ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Single Tap Confirmed ( e : ĠMotion Event ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe Ġ?: Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon View ClickListener ?. onClick ( imageView ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġcontainer . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbackground . alpha Ġ= Ġ 2 5 5 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset On Touch Listener ( this @ L ou pe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd On Layout ChangeListener ( this @ L ou pe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscale Gesture Detector Ġ= ĠScale Gesture Detector ( context , Ġon Scale Gesture Listener ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgesture Detector Ġ= ĠGest ure Detector ( context , Ġon Gesture Listener ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsc roller Ġ= ĠOver Scroller ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdrag Dismiss Distance In Px Ġ= ĠTyped Value . apply Dimension ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTyped Value . COMPLEX _ UNIT _ DIP , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdrag Dismiss Distance In Dp . toFloat (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresources . display Metrics ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠimageView . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimage Matrix Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġy Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġanimate (). cancel () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscale Type Ġ= ĠImageView . Scale Type . MATRIX ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar ĠimageView Ref : ĠWeak Reference < ImageView > Ġ= ĠWeak Reference ( imageView ) ĊĠĠĠ Ġprivate Ġvar Ġcontainer Ref : ĠWeak Reference < ViewGroup > Ġ= ĠWeak Reference ( container ) ĊĊĠĠĠ Ġoverride Ġfun Ġon Touch ( view : ĠView ?, Ġevent : ĠMotion Event ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġevent Ġ?: Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġval Ġcontainer Ġ= Ġcontainer Ref . get () Ġ?: Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠ Ġcontainer . parent . request Dis allow Intercept Touch Event ( scale Ġ!= Ġmin Scale ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! imageView . isEnabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( is View Translate Animation Running ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġscale Event Ġ= Ġscale Gesture Detector ?. on Touch Event ( event ) ĊĠĠĠĠĠĠĠ Ġval Ġis Scale Animation Is Running Ġ= Ġscale Ġ< Ġmin Scale ĊĠĠĠĠĠĠĠ Ġif Ġ( scale Event Ġ!= Ġscale Gesture Detector ?. is InProgress Ġ&& Ġ! is Scale Animation Is Running ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġhandle Ġsingle Ġtouch Ġgesture Ġwhen Ġscaling Ġprocess Ġis Ġnot Ġrunning ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgesture Detector ?. on Touch Event ( event ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġwhen Ġ( event . action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ DOWN Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfl ing Animator . cancel () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ UP Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscale Ġ== Ġmin Scale Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is View Translate Animation Running ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdismiss Or Restore IfNeeded () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscale Ġ> Ġmin Scale Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconstr ain Bitmap Bounds ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġzoom Out To Minimum Scale ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġset Transform () ĊĠĠĠĠĠĠĠ ĠimageView . post Invalidate () ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Layout Change ( ĊĠĠĠĠĠĠĠ Ġview : ĠView ?, ĊĠĠĠĠĠĠĠ Ġleft : ĠInt , ĊĠĠĠĠĠĠĠ Ġtop : ĠInt , ĊĠĠĠĠĠĠĠ Ġright : ĠInt , ĊĠĠĠĠĠĠĠ Ġbottom : ĠInt , ĊĠĠĠĠĠĠĠ Ġold Left : ĠInt , ĊĠĠĠĠĠĠĠ Ġold Top : ĠInt , ĊĠĠĠĠĠĠĠ Ġold Right : ĠInt , ĊĠĠĠĠĠĠĠ Ġold Bottom : ĠInt ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġcontainer Ġ= Ġcontainer Ref . get () Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠ ĠimageView . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsetup Layout ( left , Ġtop , Ġright , Ġbottom ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Y Ġ= Ġy ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( use Fl ing To Dismiss Gesture ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Drag To Dismiss Distance ( DEFAULT _ DR AG _ DIS MIS S _ DISTANCE _ IN _ VIEW _ HEIGHT _ RATIO ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Drag To Dismiss Distance ( DEFAULT _ DR AG _ DIS MIS S _ DISTANCE _ IN _ DP ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontainer . background . alpha Ġ= Ġ 2 5 5 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Transform () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpost Invalidate () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstart Vertical Translate Animation ( vel Y : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠ Ġis View Translate Animation Running Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ ĠimageView . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtranslation Y Ġ= Ġif Ġ( vel Y Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal View Bounds . top Ġ+ Ġheight Ġ- Ġtop ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal View Bounds . top Ġ- Ġheight Ġ- Ġtop ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġanimate () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Duration ( dismiss Animation Duration ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Interpolator ( dismiss Animation Interpolator ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. translation Y ( translation Y . toFloat ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Update Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġamount Ġ= Ġcalc Translation Amount () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchange Background Alpha ( amount ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon View Translate Listener ?. on View Translate ( imageView , Ġamount ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Listener ( object Ġ: ĠAn imator . Animator Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Start ( p 0 : ĠAn imator ?) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation End ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis View Translate Animation Running Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon View Translate Listener ?. on Dismiss ( imageView ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcleanup () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Cancel ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis View Translate Animation Running Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Repeat ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġno Ġop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġprocess Fl ing Bitmap ( velocity X : ĠFloat , Ġvelocity Y : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠ Ġvar Ġ( vel X , Ġvel Y ) Ġ= Ġvelocity X Ġ/ Ġscale Ġto Ġvelocity Y Ġ/ Ġscale ĊĊĠĠĠĠĠĠĠ Ġif Ġ( vel X Ġ== Ġ 0 f Ġ&& Ġvel Y Ġ== Ġ 0 f ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( vel X Ġ> ĠMAX _ FL ING _ VE LOC ITY ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvel X Ġ= ĠMAX _ FL ING _ VE LOC ITY ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( vel Y Ġ> ĠMAX _ FL ING _ VE LOC ITY ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvel Y Ġ= ĠMAX _ FL ING _ VE LOC ITY ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġ( from X , Ġfrom Y ) Ġ= Ġbitmap Bounds . left Ġto Ġbitmap Bounds . top ĊĊĠĠĠĠĠĠĠ Ġsc roller . force Finished ( true ) ĊĠĠĠĠĠĠĠ Ġsc roller . fl ing ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfrom X . round ToInt (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfrom Y . round ToInt (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvel X . round ToInt (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvel Y . round ToInt (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( viewport . right Ġ- Ġbitmap Bounds . width ()). round ToInt (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġviewport . left . round ToInt (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( viewport . bottom Ġ- Ġbitmap Bounds . height ()). round ToInt (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġviewport . top . round ToInt () ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ ĠView Compat . post Invalidate On Animation ( imageView ) ĊĊĠĠĠĠĠĠĠ Ġval Ġto X Ġ= Ġsc roller . final X . toFloat () ĊĠĠĠĠĠĠĠ Ġval Ġto Y Ġ= Ġsc roller . final Y . toFloat () ĊĊĠĠĠĠĠĠĠ Ġfl ing Animator Ġ= ĠValue Animator . of Float ( 0 f , Ġ 1 f ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġduration Ġ= Ġfl ing Animation Duration ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinterpol ator Ġ= Ġfl ing Animation Interpolator ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Update Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġamount Ġ= Ġit . animated Value Ġas ĠFloat ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Left Ġ= Ġl erp ( amount , Ġfrom X , Ġto X ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Top Ġ= Ġl erp ( amount , Ġfrom Y , Ġto Y ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbitmap Bounds . offset To ( new Left , Ġnew Top ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠView Compat . post Invalidate On Animation ( imageView ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Transform () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Listener ( object Ġ: ĠAn imator . Animator Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Start ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Bitmap Translate Animation Running Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation End ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Bitmap Translate Animation Running Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconstr ain Bitmap Bounds () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Cancel ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Bitmap Translate Animation Running Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Repeat ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġno Ġop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfl ing Animator . start () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġprocess Scroll ( distance X : ĠFloat , Ġdistance Y : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdist X Ġ= Ġif Ġ( is Horizontal Scroll Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ- distance X ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 f ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġdist Y Ġ= Ġif Ġ( is Vertical Scroll Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ- distance Y ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 f ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġoffset Bitmap ( dist X , Ġdist Y ) ĊĠĠĠĠĠĠĠ Ġset Transform () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġzoom In To Target Scale ( e : ĠMotion Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġstart Scale Ġ= Ġscale ĊĠĠĠĠĠĠĠ Ġval Ġend Scale Ġ= Ġmin Scale Ġ* Ġmax Zoom Ġ* Ġdouble Tap Zoom Scale ĊĠĠĠĠĠĠĠ Ġval Ġf ocal X Ġ= Ġe . x ĊĠĠĠĠĠĠĠ Ġval Ġf ocal Y Ġ= Ġe . y ĊĠĠĠĠĠĠĠ ĠValue Animator . of Float ( start Scale , Ġend Scale ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġduration Ġ= Ġscale Animation Duration ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinterpol ator Ġ= Ġdouble Tap Scale Animation Interpolator ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Update Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġzoom To Target Scale ( it . animated Value Ġas ĠFloat , Ġf ocal X , Ġf ocal Y ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠView Compat . post Invalidate On Animation ( imageView ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Transform () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Listener ( object Ġ: ĠAn imator . Animator Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Start ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Bitmap Scale Animation Run nin ng Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation End ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Bitmap Scale Animation Run nin ng Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( end Scale Ġ== Ġmin Scale ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġzoom To Target Scale ( min Scale , Ġf ocal X , Ġf ocal Y ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠimageView . post Invalidate () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Cancel ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Bitmap Scale Animation Run nin ng Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Repeat ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġno Ġop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ}. start () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġzoom Out To Minimum Scale ( is Over Scaling : ĠBoolean Ġ= Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġstart Scale Ġ= Ġscale ĊĠĠĠĠĠĠĠ Ġval Ġend Scale Ġ= Ġmin Scale ĊĠĠĠĠĠĠĠ Ġval Ġstart Left Ġ= Ġbitmap Bounds . left ĊĠĠĠĠĠĠĠ Ġval Ġstart Top Ġ= Ġbitmap Bounds . top ĊĠĠĠĠĠĠĠ Ġval Ġend Left Ġ= Ġcanvas Bounds . center X () Ġ- Ġimage Width Ġ* Ġmin Scale Ġ* Ġ 0 . 5 f ĊĠĠĠĠĠĠĠ Ġval Ġend Top Ġ= Ġcanvas Bounds . center Y () Ġ- Ġimage Height Ġ* Ġmin Scale Ġ* Ġ 0 . 5 f ĊĠĠĠĠĠĠĠ Ġval Ġf ocal X Ġ= Ġcanvas Bounds . center X () ĊĠĠĠĠĠĠĠ Ġval Ġf ocal Y Ġ= Ġcanvas Bounds . center Y () ĊĠĠĠĠĠĠĠ ĠValue Animator . of Float ( 0 f , Ġ 1 f ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġduration Ġ= Ġif Ġ( is Over Scaling ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġover Scale Animation Duration ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscale Animation Duration ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinterpol ator Ġ= Ġif Ġ( is Over Scaling ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġover Scale Animation Interpolator ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdouble Tap Scale Animation Interpolator ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Update Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġit . animated Value Ġas ĠFloat ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscale Ġ= Ġl erp ( value , Ġstart Scale , Ġend Scale ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Left Ġ= Ġl erp ( value , Ġstart Left , Ġend Left ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Top Ġ= Ġl erp ( value , Ġstart Top , Ġend Top ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Scale Changed Listener ?. on Scale Change ( scale Ġ/ Ġmin Scale , Ġf ocal X , Ġf ocal Y ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcalc Bounds () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbitmap Bounds . offset To ( new Left , Ġnew Top ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconstr ain Bitmap Bounds () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠView Compat . post Invalidate On Animation ( imageView ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Transform () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Listener ( object Ġ: ĠAn imator . Animator Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Start ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Bitmap Scale Animation Run nin ng Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation End ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Bitmap Scale Animation Run nin ng Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( end Scale Ġ== Ġmin Scale ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscale Ġ= Ġmin Scale ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcalc Bounds () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconstr ain Bitmap Bounds () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠimageView . post Invalidate () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Cancel ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Bitmap Scale Animation Run nin ng Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Repeat ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġno Ġop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ}. start () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġlast Dist Y Ġ= ĠFloat . NaN ĊĊĠĠĠ Ġprivate Ġfun Ġprocess Drag ( distance Y : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠ Ġif Ġ( last Dist Y . isNaN ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Dist Y Ġ= Ġdistance Y ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( imageView . y Ġ== Ġinitial Y ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon View Translate Listener ?. onStart ( imageView ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠimageView . y Ġ-= Ġdistance Y Ġ* Ġview Drag F riction Ġ// Ġif Ġview Drag Ratio Ġis Ġ 1 . 0 f , Ġview Ġtranslation Ġspeed Ġis Ġequal Ġto Ġuser Ġscrolling Ġspeed . ĊĠĠĠĠĠĠĠ Ġval Ġamount Ġ= Ġcalc Translation Amount () ĊĠĠĠĠĠĠĠ Ġchange Background Alpha ( amount ) ĊĠĠĠĠĠĠĠ Ġon View Translate Listener ?. on View Translate ( imageView , Ġamount ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdismiss Or Restore IfNeeded () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Dragging () Ġ|| Ġis View Translate Animation Running ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġdismiss Or Restore () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdismiss Or Restore () Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠ Ġif Ġ( should Trigger Drag To Dismiss Animation ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( use Fl ing To Dismiss Gesture ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart Drag To Dismiss Animation () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon View Translate Listener ?. on Dismiss ( imageView ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcleanup () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrestore View Transform () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshould Trigger Drag To Dismiss Animation () Ġ= Ġdrag Distance () Ġ> Ġdrag To Dismiss Threshold ĊĊĠĠĠ Ġprivate Ġfun Ġrestore View Transform () Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠ ĠimageView . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġanimate () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Duration ( restore Animation Duration ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Interpolator ( restore Animation Interpolator ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. translation Y (( original View Bounds . top Ġ- Ġtop ). toFloat ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Update Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġamount Ġ= Ġcalc Translation Amount () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchange Background Alpha ( amount ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon View Translate Listener ?. on View Translate ( this , Ġamount ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Listener ( object Ġ: ĠAn imator . Animator Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Start ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġno Ġop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation End ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon View Translate Listener ?. on Restore ( imageView ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Cancel ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġno Ġop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Repeat ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġno Ġop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstart Drag To Dismiss Animation () Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠ ĠimageView . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtranslation Y Ġ= Ġif Ġ( y Ġ- Ġinitial Y Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal View Bounds . top Ġ+ Ġheight Ġ- Ġtop ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal View Bounds . top Ġ- Ġheight Ġ- Ġtop ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġanimate () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Duration ( dismiss Animation Duration ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Interpolator ( Accel erate De cel erate Interpolator ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. translation Y ( translation Y . toFloat ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Update Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġamount Ġ= Ġcalc Translation Amount () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchange Background Alpha ( amount ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon View Translate Listener ?. on View Translate ( this , Ġamount ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Listener ( object Ġ: ĠAn imator . Animator Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Start ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis View Translate Animation Running Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation End ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis View Translate Animation Running Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon View Translate Listener ?. on Dismiss ( imageView ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcleanup () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Cancel ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis View Translate Animation Running Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Animation Repeat ( p 0 : ĠAn imator ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġno Ġop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġprocess Fl ing To Dismiss ( velocity Y : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( use Fl ing To Dismiss Gesture Ġ&& Ġ! is View Translate Animation Running ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( abs ( velocity Y ) Ġ< Ġminimum Fl ing Velocity ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Vertical Translate Animation ( velocity Y ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcalc Translation Amount () Ġ= ĊĠĠĠĠĠĠĠ Ġconstr ain ( ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 f , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnorm ( drag Distance (), Ġ 0 f , Ġoriginal View Bounds . height (). toFloat ()), ĊĠĠĠĠĠĠĠĠĠĠĠĠ 1 f ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġfun Ġdrag Distance () Ġ= Ġabs ( view Offset Y ()) ĊĊĠĠĠ Ġprivate Ġfun Ġis Dragging () Ġ= Ġdrag Distance () Ġ> Ġ 0 f ĊĊĠĠĠ Ġprivate Ġfun Ġview Offset Y () Ġ= ĠimageView Ref . get ()?. y Ġ?: Ġ 0 Ġ- Ġinitial Y ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġtarget Scale : Ġnew Ġscale ĊĠĠĠĠ Ġ* Ġf ocal X : Ġf ocal Ġx Ġin Ġcurrent Ġbitmap Bounds ĊĠĠĠĠ Ġ* Ġf ocal Y : Ġf ocal Ġy Ġin Ġcurrent Ġbitmap Bounds ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġzoom To Target Scale ( target Scale : ĠFloat , Ġf ocal X : ĠFloat , Ġf ocal Y : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġscale Ġ= Ġtarget Scale ĊĠĠĠĠĠĠĠ Ġval Ġlast Bounds Ġ= ĠRect F ( bitmap Bounds ) ĊĠĠĠĠĠĠĠ Ġ// Ġscale Ġhas Ġchanged , Ġre calculate Ġbitmap Ġbounds ĊĠĠĠĠĠĠĠ Ġcalc Bounds () ĊĠĠĠĠĠĠĠ Ġ// Ġoffset Ġto Ġf ocal Point ĊĠĠĠĠĠĠĠ Ġoffset To Zoom F ocal Point ( focal X , Ġf ocal Y , Ġlast Bounds , Ġbitmap Bounds ) ĊĠĠĠĠĠĠĠ Ġon Scale Changed Listener ?. on Scale Change ( target Scale Ġ/ Ġmin Scale , Ġf ocal X , Ġf ocal Y ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġset Transform () Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġtrans from . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreset () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpost Translate (- image Width Ġ/ Ġ 2 , Ġ- image Height Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpost Scale ( scale , Ġscale ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpost Translate ( bitmap Bounds . center X (), Ġbitmap Bounds . center Y ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠimageView . image Matrix Ġ= Ġtrans from ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġsetup Ġlayout ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġsetup Layout ( left : ĠInt , Ġtop : ĠInt , Ġright : ĠInt , Ġbottom : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġoriginal View Bounds . set ( left , Ġtop , Ġright , Ġbottom ) ĊĠĠĠĠĠĠĠ ĠimageView . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdrawable Ġ= ĠimageView Ref . get ()?. drawable ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbitmap Ġ= Ġ( drawable Ġas ? ĠBitmap Drawable )?. bitmap ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( width Ġ== Ġ 0 Ġ|| Ġheight Ġ== Ġ 0 Ġ|| Ġdrawable Ġ== Ġnull ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimage Width Ġ= Ġ( bitmap ?. width Ġ?: Ġdrawable . intrinsic Width ). toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimage Height Ġ= Ġ( bitmap ?. height Ġ?: Ġdrawable . intrinsic Height ). toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcanvas Width Ġ= Ġ( width Ġ- Ġpadding Left Ġ- Ġpadding Right ). toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcanvas Height Ġ= Ġ( height Ġ- Ġpadding Top Ġ- Ġpadding Bottom ). toFloat () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcalc Scale Range ( canvas Width , Ġcanvas Height , Ġimage Width , Ġimage Height ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcalc Bounds () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconstr ain Bitmap Bounds () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Ready To Draw Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinvalidate () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconstr ain Bitmap Bounds ( animate : ĠBoolean Ġ= Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠ Ġif Ġ( is Bitmap Translate Animation Running Ġ|| Ġis Bitmap Scale Animation Run nin ng ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġoffset Ġ= ĠPoint F () ĊĊĠĠĠĠĠĠĠ Ġ// Ġconstr ain Ġviewport Ġinside Ġbitmap Ġbounds ĊĠĠĠĠĠĠĠ Ġif Ġ( viewport . left Ġ< Ġbitmap Bounds . left ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset . x Ġ+= Ġviewport . left Ġ- Ġbitmap Bounds . left ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( viewport . top Ġ< Ġbitmap Bounds . top ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset . y Ġ+= Ġviewport . top Ġ- Ġbitmap Bounds . top ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( viewport . right Ġ> Ġbitmap Bounds . right ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset . x Ġ+= Ġviewport . right Ġ- Ġbitmap Bounds . right ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( viewport . bottom Ġ> Ġbitmap Bounds . bottom ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset . y Ġ+= Ġviewport . bottom Ġ- Ġbitmap Bounds . bottom ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( offset . equals ( 0 f , Ġ 0 f )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( animate ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Vertical Scroll Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbitmap Bounds . offset ( 0 f , Ġoffset . y ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoffset . y Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Horizontal Scroll Enabled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbitmap Bounds . offset ( offset . x , Ġ 0 f ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoffset . x Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstart Ġ= ĠRect F ( bitmap Bounds ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġend Ġ= ĠRect F ( bitmap Bounds ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoffset ( offset . x , Ġoffset . y ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠValue Animator . of Float ( 0 f , Ġ 1 f ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġduration Ġ= Ġover Scroll Animation Duration ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinterpol ator Ġ= Ġover Scroll Animation Interpolator ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Update Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġamount Ġ= Ġit . animated Value Ġas ĠFloat ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Left Ġ= Ġl erp ( amount , Ġstart . left , Ġend . left ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Top Ġ= Ġl erp ( amount , Ġstart . top , Ġend . top ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbitmap Bounds . offset To ( new Left , Ġnew Top ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠView Compat . post Invalidate On Animation ( imageView ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Transform () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. start () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbitmap Bounds . offset ( offset . x , Ġoffset . y ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġcalc Ġcanvas / bitmap Ġbounds ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcalc Bounds () Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠ ĠimageView . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcalc Ġcanvas Ġbounds ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas Bounds Ġ= ĠRect F ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpadding Left . toFloat (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpadding Top . toFloat (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwidth Ġ- Ġpadding Right . toFloat (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġheight Ġ- Ġpadding Bottom . toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġcalc Ġbitmap Ġbounds ĊĠĠĠĠĠĠĠ Ġbitmap Bounds Ġ= ĠRect F ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas Bounds . center X () Ġ- Ġimage Width Ġ* Ġscale Ġ* Ġ 0 . 5 f , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas Bounds . center Y () Ġ- Ġimage Height Ġ* Ġscale Ġ* Ġ 0 . 5 f , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas Bounds . center X () Ġ+ Ġimage Width Ġ* Ġscale Ġ* Ġ 0 . 5 f , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas Bounds . center Y () Ġ+ Ġimage Height Ġ* Ġscale Ġ* Ġ 0 . 5 f ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ// Ġcalc Ġviewport ĊĠĠĠĠĠĠĠ Ġviewport Ġ= ĠRect F ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax ( canvas Bounds . left , Ġbitmap Bounds . left ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax ( canvas Bounds . top , Ġbitmap Bounds . top ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmin ( canvas Bounds . right , Ġbitmap Bounds . right ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmin ( canvas Bounds . bottom , Ġbitmap Bounds . bottom ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ// Ġcheck Ġscroll Ġavailability ĊĠĠĠĠĠĠĠ Ġis Horizontal Scroll Enabled Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġis Vertical Scroll Enabled Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġif Ġ( bitmap Bounds . width () Ġ< Ġcanvas Bounds . width ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Horizontal Scroll Enabled Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( bitmap Bounds . height () Ġ< Ġcanvas Bounds . height ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Vertical Scroll Enabled Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġoffset Bitmap ( offset X : ĠFloat , Ġoffset Y : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbitmap Bounds . offset ( offset X , Ġoffset Y ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġcalc Ġmin / max Ġscale Ġand Ġset Ġinitial Ġscale ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcalc Scale Range ( ĊĠĠĠĠĠĠĠ Ġcanvas Width : ĠFloat , ĊĠĠĠĠĠĠĠ Ġcanvas Height : ĠFloat , ĊĠĠĠĠĠĠĠ Ġbitmap Width : ĠFloat , ĊĠĠĠĠĠĠĠ Ġbitmap Height : ĠFloat ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcanvas Ratio Ġ= Ġcanvas Height Ġ/ Ġcanvas Width ĊĠĠĠĠĠĠĠ Ġval Ġbitmap Ratio Ġ= Ġbitmap Height Ġ/ Ġbitmap Width ĊĠĠĠĠĠĠĠ Ġmin Scale Ġ= Ġif Ġ( canvas Ratio Ġ> Ġbitmap Ratio ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas Width Ġ/ Ġbitmap Width ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcanvas Height Ġ/ Ġbitmap Height ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġscale Ġ= Ġmin Scale ĊĠĠĠĠĠĠĠ Ġmax Scale Ġ= Ġmin Scale Ġ* Ġmax Zoom ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġcalc New Scale ( new Scale : ĠFloat ): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġmin ( max Scale , Ġnew Scale Ġ* Ġscale ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconstr ain ( min : ĠFloat , Ġvalue : ĠFloat , Ġmax : ĠFloat ): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġmax ( min ( value , Ġmax ), Ġmin ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġoffset To Zoom F ocal Point ( ĊĠĠĠĠĠĠĠ Ġf ocal X : ĠFloat , ĊĠĠĠĠĠĠĠ Ġf ocal Y : ĠFloat , ĊĠĠĠĠĠĠĠ Ġold Bounds : ĠRect F , ĊĠĠĠĠĠĠĠ Ġnew Bounds : ĠRect F ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġold X Ġ= Ġconstr ain ( viewport . left , Ġf ocal X , Ġviewport . right ) ĊĠĠĠĠĠĠĠ Ġval Ġold Y Ġ= Ġconstr ain ( viewport . top , Ġf ocal Y , Ġviewport . bottom ) ĊĠĠĠĠĠĠĠ Ġval Ġnew X Ġ= Ġmap ( old X , Ġold Bounds . left , Ġold Bounds . right , Ġnew Bounds . left , Ġnew Bounds . right ) ĊĠĠĠĠĠĠĠ Ġval Ġnew Y Ġ= Ġmap ( old Y , Ġold Bounds . top , Ġold Bounds . bottom , Ġnew Bounds . top , Ġnew Bounds . bottom ) ĊĠĠĠĠĠĠĠ Ġoffset Bitmap ( old X Ġ- Ġnew X , Ġold Y Ġ- Ġnew Y ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmap ( ĊĠĠĠĠĠĠĠ Ġvalue : ĠFloat , ĊĠĠĠĠĠĠĠ Ġsrc Start : ĠFloat , ĊĠĠĠĠĠĠĠ Ġsrc Stop : ĠFloat , ĊĠĠĠĠĠĠĠ Ġdst Start : ĠFloat , ĊĠĠĠĠĠĠĠ Ġdst Stop : ĠFloat ĊĠĠĠ Ġ): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( src Stop Ġ- Ġsrc Start Ġ== Ġ 0 f ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 f ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ(( value Ġ- Ġsrc Start ) Ġ* Ġ( dst Stop Ġ- Ġdst Start ) Ġ/ Ġ( src Stop Ġ- Ġsrc Start )) Ġ+ Ġdst Start ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġl erp ( amt : ĠFloat , Ġstart : ĠFloat , Ġstop : ĠFloat ): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġstart Ġ+ Ġ( stop Ġ- Ġstart ) Ġ* Ġamt ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnorm ( value : ĠFloat , Ġstart : ĠFloat , Ġstop : ĠFloat ): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġvalue Ġ/ Ġ( stop Ġ- Ġstart ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġchange Background Alpha ( amount : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcontainer Ġ= Ġcontainer Ref . get () Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġnew Alpha Ġ= Ġ(( 1 . 0 f Ġ- Ġamount ) Ġ* Ġ 2 5 5 ). round ToInt () ĊĠĠĠĠĠĠĠ Ġcontainer . background . mutate (). alpha Ġ= Ġnew Alpha ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġset Drag To Dismiss Distance ( distance : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġdrag To Dismiss Threshold Ġ= ĠTyped Value . apply Dimension ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTyped Value . COMPLEX _ UNIT _ DIP , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdistance . toFloat (), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠimageView . context . resources . display Metrics ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġset Drag To Dismiss Distance ( height Ratio : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠimageView Ġ= ĠimageView Ref . get () Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġdrag To Dismiss Threshold Ġ= ĠimageView . height Ġ* Ġheight Ratio ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdismiss () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠAn imate Ġdown Ġoff screen Ġ( the Ġfinish Ġlistener Ġwill Ġcall Ġthe Ġcleanup Ġmethod ) ĊĠĠĠĠĠĠĠ Ġstart Vertical Translate Animation ( MIN _ FL ING _ VE LOC ITY ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġcleanup () Ġ{ ĊĠĠĠĠĠĠĠ Ġcontainer Ref . get ()?. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset On Touch Listener ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġremove On Layout ChangeListener ( null ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠimageView Ref . clear () ĊĠĠĠĠĠĠĠ Ġcontainer Ref . clear () ĊĠĠĠ Ġ} Ċ } Ċ