package Ġio . github . dr umber . k its une . ui . details . photo view Ċ Ċ import Ġandroid . Manifest Ċ import Ġandroid . annotation . Suppress Lint Ċ import Ġandroid . content . Intent Ċ import Ġandroid . content . pm . PackageManager Ċ import Ġandroid . net . Uri Ċ import Ġandroid . os . Build Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . os . Handler Ċ import Ġandroid . os . Looper Ċ import Ġandroid . view . View Ċ import Ġandroid . widget . Toast Ċ import Ġandroidx . core . app . Activity Compat Ċ import Ġandroidx . core . content . Context Compat Ċ import Ġandroidx . core . view . Window Insets Compat Ċ import Ġandroidx . core . view . Window Insets Controller Compat Ċ import Ġandroidx . core . view . isVisible Ċ import Ġandroidx . lifecycle . lifecycle Scope Ċ import Ġandroidx . navigation . nav Args Ċ import Ġapp . future d . ha uler . setOn Drag Activity Listener Ċ import Ġapp . future d . ha uler . setOn Drag Dis missed Listener Ċ import Ġio . github . dr umber . k its une . G lide App Ċ import Ġio . github . dr umber . k its une . R Ċ import Ġio . github . dr umber . k its une . databinding . Activity Photo View Binding Ċ import Ġio . github . dr umber . k its une . ui . base . Base Activity Ċ import Ġio . github . dr umber . k its une . util . extensions .* Ċ import Ġio . github . dr umber . k its une . util . save Image In Gallery Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . with Context Ċ Ċ class ĠPhoto View Activity Ġ: ĠBase Activity ( ĊĠĠĠ ĠR . layout . activity _ photo _ view , ĊĠĠĠ Ġtrue , ĊĠĠĠ Ġfalse , ĊĠĠĠ Ġfalse Ċ ) Ġ{ ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġbinding : ĠActivity Photo View Binding ĊĊĠĠĠ Ġprivate Ġval Ġargs Ġby Ġnav Args < Photo View Activity Args >() ĊĊĠĠĠ Ġprivate Ġvar Ġis Fullscreen : ĠBoolean Ġ= Ġfalse ĊĊĠĠĠ Ġprivate Ġval Ġhide Handler Ġ= ĠHandler ( Looper . get Main Looper ()) ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĊĠĠĠĠĠĠĠ Ġbinding Ġ= ĠActivity Photo View Binding . inflate ( layout Inflater ) ĊĠĠĠĠĠĠĠ ĠsetContentView ( binding . root ) ĊĊĠĠĠĠĠĠĠ Ġset StatusBar Color Res ( R . color . trans luc ent _ system _ overlay ) ĊĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= Ġ 2 7 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwindow . navigation Bar Color Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContext Compat . getColor ( this , ĠR . color . trans luc ent _ system _ overlay ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Night Mode ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclear Light StatusBar () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclear Light NavigationBar () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠWindow Insets Controller Compat ( window , Ġbinding . root ). system Bars Behavior Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠWindow Insets Controller Compat . BE HAV IOR _ SHOW _ TRAN SI ENT _ BAR S _ BY _ SW I PE ĊĊĠĠĠĠĠĠĠ Ġbinding . photo View . setOnClickListener Ġ{ Ġtoggle System Ui () Ġ} ĊĊĠĠĠĠĠĠĠ ĠG lide App . with ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. load ( args . imageUrl ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. dont Transform () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. into ( binding . photo View ) ĊĊĠĠĠĠĠĠĠ Ġbinding . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbtn Close . reset Auto Hide On Touch () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbtn Save . reset Auto Hide On Touch () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbtn Open . reset Auto Hide On Touch () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġbtn Close . setOnClickListener Ġ{ Ġfinish () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbtn Save . setOnClickListener Ġ{ Ġsave Image () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbtn Open . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġintent Ġ= ĠIntent ( Intent . ACTION _ VIEW , ĠUri . parse ( args . imageUrl )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartActivity ( intent ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġbinding . ha uler View . setOn Drag Dis missed Listener Ġ{ Ġfinish () Ġ} ĊĠĠĠĠĠĠĠ Ġbinding . ha uler View . setOn Drag Activity Listener Ġ{ Ġ_, Ġraw Offset Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfade Ġbackground Ġalpha Ġon Ġdrag ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġalpha Ġ= Ġ( 1 . 0 f Ġ- Ġraw Offset ) Ġ* Ġ 2 5 5 . 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . photo Background . background . alpha Ġ= Ġalpha . toInt () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġreset Ġalpha ĊĠĠĠĠĠĠĠ Ġbinding . photo Background . background . alpha Ġ= Ġ 2 5 5 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Post Create ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Post Create ( savedInstanceState ) ĊĊĠĠĠĠĠĠĠ Ġhide Handler . remove Callbacks ( hide Runnable ) ĊĠĠĠĠĠĠĠ Ġhide Handler . post Delayed ( hide Runnable , ĠUI _ ANIM ATION _ DELAY ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġhide Runnable Ġ= ĠRunnable Ġ{ ĊĠĠĠĠĠĠĠ Ġhide System Ui () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRe sets Ġany Ġhide Ġcallback Ġto Ġavoid Ġhiding Ġcontrols Ġwhile Ġthe Ġuser Ġis Ġinteracting . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġreset Auto Hide Time () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Fullscreen ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhide Handler . remove Callbacks ( hide Runnable ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhide Handler . post Delayed ( hide Runnable , ĠAUTO _ HIDE _ DELAY _ M ILL IS ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress Lint (" Click ableView Accessibility ") ĊĠĠĠ Ġprivate Ġfun ĠView . reset Auto Hide On Touch () Ġ{ ĊĠĠĠĠĠĠĠ Ġset On Touch Listener Ġ{ Ġ_, Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreset Auto Hide Time () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhide System Ui () Ġ{ ĊĠĠĠĠĠĠĠ Ġis Fullscreen Ġ= Ġtrue ĊĠĠĠĠĠĠĠ ĠWindow Insets Controller Compat ( window , Ġbinding . root ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. hide ( Window Insets Compat . Type . status Bars () Ġor ĠWindow Insets Compat . Type . navigation Bars ()) ĊĠĠĠĠĠĠĠ Ġbinding . fullscreen Content Controls . isVisible Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow System Ui () Ġ{ ĊĠĠĠĠĠĠĠ Ġis Fullscreen Ġ= Ġfalse ĊĠĠĠĠĠĠĠ ĠWindow Insets Controller Compat ( window , Ġbinding . root ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. show ( Window Insets Compat . Type . status Bars () Ġor ĠWindow Insets Compat . Type . navigation Bars ()) ĊĠĠĠĠĠĠĠ Ġbinding . fullscreen Content Controls . isVisible Ġ= Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġtoggle System Ui () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Fullscreen ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhide Handler . remove Callbacks ( hide Runnable ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( AUTO _ HIDE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhide Handler . post Delayed ( hide Runnable , ĠAUTO _ HIDE _ DELAY _ M ILL IS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow System Ui () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhide System Ui () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Request Permissions Result ( ĊĠĠĠĠĠĠĠ Ġrequest Code : ĠInt , ĊĠĠĠĠĠĠĠ Ġpermissions : ĠArray < out ĠString >, ĊĠĠĠĠĠĠĠ Ġgrant Results : ĠInt Array ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Request Permissions Result ( request Code , Ġpermissions , Ġgrant Results ) ĊĠĠĠĠĠĠĠ Ġif Ġ( request Code Ġ== ĠWRITE _ EXTERNAL _ STORAGE _ REQUEST _ CODE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġgrant Results . isNotEmpty () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġgrant Results [ 0 ] Ġ== ĠPackage Manager . PERMISSION _ GRAN TED ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsave Image () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( request Code Ġ== ĠWRITE _ EXTERNAL _ STORAGE _ REQUEST _ CODE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . error _ requires _ external _ storage _ permission , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . LENGTH _ LONG ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ). show () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsave Image () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġcheck Ġif Ġpermission Ġis Ġgranted ĊĠĠĠĠĠĠĠ Ġif Ġ( should Request Write Permission ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠActivity Compat . request Permissions ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠarrayOf ( Manifest . permission . WRITE _ EXTERNAL _ STORAGE ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠWRITE _ EXTERNAL _ STORAGE _ REQUEST _ CODE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġlifecycle Scope . launch ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbitmap Ġ= ĠG lide App . with ( this @ Photo View Activity ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. as Bitmap () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. load ( args . imageUrl ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. submit () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. get () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsuccess Ġ= Ġsave Image In Gallery ( bitmap , Ġargs . title ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( success ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis @ Photo View Activity , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . string . info _ image _ saved _ in _ gallery , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . LENGTH _ SHORT ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). show () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Something Wrong Toast () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġif Ġexternal Ġstorage Ġwrite Ġpermission Ġmust Ġbe Ġrequested . ĊĠĠĠĠ Ġ* ĠOn ĠAndroid Ġ 1 0 + Ġthis Ġis Ġno Ġlonger Ġrequired , Ġsee ĊĠĠĠĠ Ġ* Ġ[ here ]( https :// developer . android . com / training / data - storage / shared / media # scoped _ storage _ enabled ). ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġshould Request Write Permission (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠBuild . VERSION . SDK _ INT Ġ< ĠBuild . VERSION _ CODES . Q Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContext Compat . check Self Permission ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠManifest . permission . WRITE _ EXTERNAL _ STORAGE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ!= ĠPackage Manager . PERMISSION _ GRAN TED ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠWhether Ġor Ġnot Ġthe Ġsystem ĠUI Ġshould Ġbe Ġauto - hidden Ġafter ĊĠĠĠĠĠĠĠĠ Ġ* Ġ[ AUTO _ HIDE _ DELAY _ M ILL IS ] Ġmilliseconds . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠAUTO _ HIDE Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠIf Ġ[ AUTO _ HIDE ] Ġis Ġset , Ġthe Ġnumber Ġof Ġmilliseconds Ġafter ĊĠĠĠĠĠĠĠĠ Ġ* Ġhiding Ġthe Ġsystem ĠUI . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠAUTO _ HIDE _ DELAY _ M ILL IS Ġ= Ġ 5 0 0 0 L ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠHide Ġsystem ĠUI Ġafter Ġthis Ġamount Ġof Ġmilliseconds . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠUI _ ANIM ATION _ DELAY Ġ= Ġ 5 0 0 L ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠWRITE _ EXTERNAL _ STORAGE _ REQUEST _ CODE Ġ= Ġ 1 ĊĠĠĠ Ġ} Ċ }