Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Room Park Android
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vladislav Bogdashkin
Room Park Android
Commits
c6397e8d
Commit
c6397e8d
authored
Mar 06, 2020
by
Vladislav Bogdashkin
🎣
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
integrated glide
add photo slider fix photo adapter semi-working functionaly for photo screen
parent
d95a21a3
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
644 additions
and
13 deletions
+644
-13
Project.xml
.idea/codeStyles/Project.xml
+3
-0
build.gradle
app/build.gradle
+5
-0
AlbumListAdapter.kt
...mpark/presentation/screen/albums/util/AlbumListAdapter.kt
+0
-2
ScreenController.kt
...al/roompark/presentation/screen/photo/ScreenController.kt
+24
-6
PhotoPreviewSlider.kt
...park/presentation/screen/photo/util/PhotoPreviewSlider.kt
+191
-0
PhotoViewAdapter.kt
...ompark/presentation/screen/photo/util/PhotoViewAdapter.kt
+14
-4
Renderer.kt
...isual/roompark/presentation/screen/photo/util/Renderer.kt
+403
-0
photo_view_screen.xml
app/src/main/res/layout/photo_view_screen.xml
+3
-1
dependencies.gradle
dependencies.gradle
+1
-0
No files found.
.idea/codeStyles/Project.xml
View file @
c6397e8d
<component
name=
"ProjectCodeStyleConfiguration"
>
<code_scheme
name=
"Project"
version=
"173"
>
<AndroidXmlCodeStyleSettings>
<option
name=
"ARRANGEMENT_SETTINGS_MIGRATED_TO_191"
value=
"true"
/>
</AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings>
<option
name=
"CODE_STYLE_DEFAULTS"
value=
"KOTLIN_OFFICIAL"
/>
</JetCodeStyleSettings>
...
...
app/build.gradle
View file @
c6397e8d
...
...
@@ -159,6 +159,11 @@ dependencies {
//Photo view
implementation
"com.github.chrisbanes:PhotoView:$photoViewVersion"
//Glide
implementation
"com.github.bumptech.glide:glide:$glideVersion"
annotationProcessor
"com.github.bumptech.glide:compiler:$glideVersion"
//Tests
testImplementation
'junit:junit:4.12'
androidTestImplementation
'androidx.test:runner:1.2.0'
...
...
app/src/main/java/com/biganto/visual/roompark/presentation/screen/albums/util/AlbumListAdapter.kt
View file @
c6397e8d
...
...
@@ -10,8 +10,6 @@ import com.biganto.visual.roompark.base.RoomParkApplication
import
com.biganto.visual.roompark.domain.model.AlbumSortedModel
import
com.biganto.visual.roompark.domain.model.PhotoModel
import
com.biganto.visual.roompark.domain.model.PhotoResolutionModel
import
com.biganto.visual.roompark.presentation.screen.photo.util.PhotosAdapter
import
com.biganto.visual.roompark.presentation.screen.photo.util.PhotosViewHolder
import
com.biganto.visual.roompark.presentation.screen.settings.util.CommonRecyclerAdapter
import
com.biganto.visual.roompark.presentation.screen.settings.util.CommonViewHolder
import
com.biganto.visual.roompark.util.view_utils.image_view.RoundedImageView
...
...
app/src/main/java/com/biganto/visual/roompark/presentation/screen/photo/ScreenController.kt
View file @
c6397e8d
...
...
@@ -9,7 +9,8 @@ import com.biganto.visual.roompark.R
import
com.biganto.visual.roompark.base.RoomParkApplication
import
com.biganto.visual.roompark.base.RoomParkMainActivity
import
com.biganto.visual.roompark.conductor.BigantoBaseController
import
com.biganto.visual.roompark.presentation.screen.photo.util.PhotoViewerAdapter
import
com.biganto.visual.roompark.presentation.screen.photo.util.PhotoPreviewSlider
import
com.biganto.visual.roompark.presentation.screen.photo.util.PhotosAdapter
import
com.google.android.material.textview.MaterialTextView
import
com.squareup.picasso.Picasso
import
timber.log.Timber
...
...
@@ -39,11 +40,26 @@ class PhotoScreenController :
@BindView
(
R
.
id
.
photo_frame
)
lateinit
var
photoViewPager
:
ViewPager2
@BindView
(
R
.
id
.
photosPreviewSlider
)
lateinit
var
slider
:
PhotoPreviewSlider
private
fun
bindRecycler
()
{
photoViewPager
.
isNestedScrollingEnabled
=
false
photoViewPager
.
offscreenPageLimit
=
2
photoViewPager
.
adapter
=
PhotoViewerAdapter
()
photoViewPager
.
adapter
=
PhotosAdapter
()
setVewPager
()
}
private
fun
setVewPager
(){
val
ap
=
PhotosAdapter
()
photoViewPager
.
adapter
=
ap
photoViewPager
.
orientation
=
ViewPager2
.
ORIENTATION_HORIZONTAL
photoViewPager
.
offscreenPageLimit
=
2
ap
.
notifyDataSetChanged
()
photoViewPager
.
invalidate
()
slider
.
setUpViewPager
(
photoViewPager
)
}
override
fun
onViewBound
(
v
:
View
)
{
...
...
@@ -94,11 +110,13 @@ class PhotoScreenController :
lateinit
var
picassoAsync
:
Picasso
private
fun
render
(
viewState
:
PhotoScreenViewState
.
PhotoListLoaded
)
{
(
photoViewPager
.
adapter
as
Photo
Viewer
Adapter
).
setItems
(
(
photoViewPager
.
adapter
as
Photo
s
Adapter
).
setItems
(
viewState
.
list
.
asSequence
().
sortedBy
{
it
.
sort
}.
toList
()
)
photoViewPager
.
currentItem
=
(
photoViewPager
.
adapter
as
PhotoViewerAdapter
)
.
getItemPosition
(
viewState
.
selectedId
)
photoViewPager
.
currentItem
=
viewState
.
selectedId
slider
.
visibility
=
View
.
VISIBLE
slider
.
setUpViewPager
(
photoViewPager
)
}
private
fun
render
(
viewState
:
PhotoScreenViewState
.
AldumFetched
)
{
...
...
@@ -107,7 +125,7 @@ class PhotoScreenController :
private
fun
render
(
viewState
:
PhotoScreenViewState
.
PhotoFetched
){
(
photoViewPager
.
adapter
as
Photo
Viewer
Adapter
).
setItems
(
arrayListOf
(
viewState
.
model
))
(
photoViewPager
.
adapter
as
Photo
s
Adapter
).
setItems
(
arrayListOf
(
viewState
.
model
))
}
private
fun
render
(
viewState
:
PhotoScreenViewState
.
PhotoSelected
){
// (photoViewPager.adapter as PhotoViewerAdapter).setItems(arrayListOf(viewState.model))
...
...
app/src/main/java/com/biganto/visual/roompark/presentation/screen/photo/util/PhotoPreviewSlider.kt
0 → 100644
View file @
c6397e8d
package
com.biganto.visual.roompark.presentation.screen.photo.util
import
android.content.Context
import
android.graphics.SurfaceTexture
import
android.util.AttributeSet
import
android.view.GestureDetector
import
android.view.MotionEvent
import
android.view.TextureView
import
android.view.View
import
androidx.viewpager2.widget.ViewPager2
import
kotlinx.android.synthetic.main.photo_page_viewholder.view.*
import
timber.log.Timber
/**
* Created by Vladislav Bogdashkin on 22.12.2019.
*/
class
PhotoPreviewSlider
@JvmOverloads
constructor
(
context
:
Context
,
attrs
:
AttributeSet
?
=
null
,
defStyleAttr
:
Int
=
0
)
:
TextureView
(
context
,
attrs
,
defStyleAttr
)
,
TextureView
.
SurfaceTextureListener
{
private
var
texThread
:
RendererThread
?=
null
private
var
adapter
:
PhotosAdapter
?
=
null
private
var
vp
:
ViewPager2
?
=
null
fun
setUpViewPager
(
viewpager
:
ViewPager2
)
{
this
.
adapter
=
viewpager
.
adapter
as
PhotosAdapter
with
(
viewpager
)
{
setPageTransformer
{
page
,
position
->
setParallaxTransformation
(
page
,
position
)
}
registerOnPageChangeCallback
(
object
:
ViewPager2
.
OnPageChangeCallback
()
{
var
actualPosition
=
0
override
fun
onPageScrolled
(
position
:
Int
,
positionOffset
:
Float
,
positionOffsetPixels
:
Int
)
{
if
(
position
==
actualPosition
){
processSliding
(
positionOffset
)
}
else
{
processSliding
(
positionOffset
-
1
)
}
super
.
onPageScrolled
(
position
,
positionOffset
,
positionOffsetPixels
)
}
override
fun
onPageSelected
(
position
:
Int
)
{
actualPosition
=
position
texThread
?.
setIndex
(
position
)
super
.
onPageSelected
(
position
)
}
})
}
vp
=
viewpager
}
private
fun
setParallaxTransformation
(
page
:
View
,
position
:
Float
)
{
page
.
apply
{
when
{
position
<
-
1
->
// [-Infinity,-1)
// This page is way off-screen to the left.
alpha
=
1f
position
<
-
1
->
// [-1,0){
{
}
position
<=
1
->
{
// [-1,1]
photo_view
.
translationX
=
-
position
*
(
width
/
2
)
// slider.processSliding(position)
}
else
->
// (1,+Infinity]
{
// This page is way off-screen to the right.
alpha
=
1f
}
}
}
}
fun
processSliding
(
_position
:
Float
){
texThread
?.
setSlidePosition
(
_position
)
}
val
gestureDetector
=
GestureDetector
(
context
,
object
:
GestureDetector
.
SimpleOnGestureListener
(){
override
fun
onDoubleTap
(
e
:
MotionEvent
?):
Boolean
{
Timber
.
d
(
"double tap"
)
return
true
}
override
fun
onScroll
(
e1
:
MotionEvent
?,
e2
:
MotionEvent
?,
distanceX
:
Float
,
distanceY
:
Float
):
Boolean
{
mIsScrolling
=
true
Timber
.
d
(
"scroll"
)
texThread
?.
perfomDrag
(
distanceX
)
return
true
}
override
fun
onDown
(
e
:
MotionEvent
?):
Boolean
{
Timber
.
d
(
"down"
)
return
true
}
})
private
var
mIsScrolling
=
false
init
{
surfaceTextureListener
=
this
val
gestureListener
=
object
:
OnTouchListener
{
private
var
gesture
:
GestureDetector
=
gestureDetector
override
fun
onTouch
(
v
:
View
,
event
:
MotionEvent
):
Boolean
{
Timber
.
w
(
" ON TOUCH EVENT!"
)
val
performTouch
=
gesture
.
onTouchEvent
(
event
)
if
(
performTouch
)
return
true
if
(
event
.
action
==
MotionEvent
.
ACTION_UP
)
{
if
(
mIsScrolling
)
{
Timber
.
d
(
"OnTouchListener --> onTouch ACTION_UP"
)
mIsScrolling
=
false
texThread
?.
perfomDrag
(
null
,
mIsScrolling
)
}
}
if
(
event
.
action
==
MotionEvent
.
ACTION_BUTTON_PRESS
)
performClick
()
return
false
}
}
setOnTouchListener
(
gestureListener
)
}
override
fun
onSizeChanged
(
w
:
Int
,
h
:
Int
,
oldw
:
Int
,
oldh
:
Int
)
{
Timber
.
d
(
"On Size Chagned"
)
super
.
onSizeChanged
(
w
,
h
,
oldw
,
oldh
)
}
override
fun
onSurfaceTextureSizeChanged
(
surface
:
SurfaceTexture
?,
width
:
Int
,
height
:
Int
)
{
print
(
" onSurfaceTextureSizeChanged"
)
texThread
?.
setSize
(
width
,
height
)
//Ignored
}
override
fun
onSurfaceTextureUpdated
(
surface
:
SurfaceTexture
?)
{
print
(
" onSurfaceTextureUpdated"
)
//Ignored
}
override
fun
onSurfaceTextureDestroyed
(
surface
:
SurfaceTexture
?):
Boolean
{
texThread
?.
isStopped
=
true
return
true
}
override
fun
onSurfaceTextureAvailable
(
surface
:
SurfaceTexture
?,
width
:
Int
,
height
:
Int
)
{
Timber
.
d
(
"avaliable surf: $surface"
)
surface
?.
let
{
if
(
texThread
?.
isAlive
==
true
)
return
texThread
=
RendererThread
(
context
,
it
)
texThread
?.
setSize
(
width
,
height
)
texThread
?.
onChangePage
=
{
ind
->
vp
?.
setCurrentItem
(
ind
,
false
)}
texThread
?.
start
()
adapter
?.
let
{
adapter
->
texThread
?.
setAdapter
(
adapter
.
photosPreviewList
)
// texThread?.setIndex(min(_l.size,2))
}
?:
error
(
"adapter not ready!"
)
}
}
override
fun
onDetachedFromWindow
()
{
super
.
onDetachedFromWindow
()
texThread
?.
isStopped
=
true
}
}
app/src/main/java/com/biganto/visual/roompark/presentation/screen/photo/util/
AlbumList
Adapter.kt
→
app/src/main/java/com/biganto/visual/roompark/presentation/screen/photo/util/
PhotoView
Adapter.kt
View file @
c6397e8d
...
...
@@ -8,7 +8,8 @@ import com.biganto.visual.roompark.domain.model.PhotoModel
import
com.biganto.visual.roompark.domain.model.PhotoResolutionModel
import
com.biganto.visual.roompark.presentation.screen.settings.util.CommonRecyclerAdapter
import
com.biganto.visual.roompark.presentation.screen.settings.util.CommonViewHolder
import
com.biganto.visual.roompark.util.view_utils.image_view.RoundedImageView
import
com.github.chrisbanes.photoview.PhotoView
import
timber.log.Timber
/**
* Created by Vladislav Bogdashkin on 16.10.2019.
...
...
@@ -16,14 +17,23 @@ import com.biganto.visual.roompark.util.view_utils.image_view.RoundedImageView
class
PhotosAdapter
:
CommonRecyclerAdapter
<
PhotosViewHolder
,
PhotoModel
>()
{
val
photosPreviewList
:
List
<
String
>
get
()
{
val
ret
=
list
.
map
{
it
.
resolutionList
.
lowelest
()
?.
url
?:
error
(
"No res urls!"
)}.
toList
()
Timber
.
d
(
"$ret"
)
return
ret
}
override
val
vhKlazz
=
PhotosViewHolder
::
class
override
fun
getVhLayout
():
Int
=
R
.
layout
.
photo_p
review
_viewholder
override
fun
getVhLayout
():
Int
=
R
.
layout
.
photo_p
age
_viewholder
}
class
PhotosViewHolder
(
itemView
:
View
)
:
CommonViewHolder
<
PhotoModel
>(
itemView
)
{
@BindView
(
R
.
id
.
photo_
preview_imageview
)
lateinit
var
photoPreview
:
RoundedImage
View
@BindView
(
R
.
id
.
photo_
view
)
lateinit
var
photoPreview
:
Photo
View
private
val
picassoAsync
by
lazy
{
return
@lazy
RoomParkApplication
.
component
.
providePicassoAsync
()
...
...
@@ -39,5 +49,5 @@ class PhotosViewHolder(itemView: View) : CommonViewHolder<PhotoModel>(itemView)
}}
}
fun
List
<
PhotoResolutionModel
>.
lowelest
()
=
private
fun
List
<
PhotoResolutionModel
>.
lowelest
()
=
this
.
minBy
{
it
.
resWidth
*
it
.
resHeight
}
\ No newline at end of file
app/src/main/java/com/biganto/visual/roompark/presentation/screen/photo/util/Renderer.kt
0 → 100644
View file @
c6397e8d
package
com.biganto.visual.roompark.presentation.screen.photo.util
import
android.content.Context
import
android.graphics.*
import
android.graphics.drawable.Drawable
import
android.view.Surface
import
com.bumptech.glide.Glide
import
com.bumptech.glide.load.engine.DiskCacheStrategy
import
com.bumptech.glide.request.RequestOptions
import
com.bumptech.glide.request.target.CustomTarget
import
com.bumptech.glide.request.transition.Transition
import
timber.log.Timber
import
kotlin.math.abs
import
kotlin.math.absoluteValue
import
kotlin.math.sign
import
kotlin.math.sin
/**
* Created by Vladislav Bogdashkin on 18.07.2019.
*/
private
const
val
CONST_SLEEP_THRESHOLD
=
8L
private
const
val
CONST_CENTER_PHOTO_BORDER_PX
=
8
private
const
val
CONST_CENTER_HEIGHT_DIFF_PX
=
0
private
const
val
CONST_HEIGHT_MARGIN_BORDER_PX
=
10
private
const
val
CONST_DIFF_BORDER_PX
=
1
private
const
val
CONST_DECAY_TIMER
=
500L
class
RendererThread
(
val
context
:
Context
,
val
surface
:
SurfaceTexture
)
:
Thread
(){
private
val
dens
:
Float
by
lazy
{
context
.
resources
.
displayMetrics
.
density
}
private
val
SLEEP_THRESHOLD
get
()
=
CONST_SLEEP_THRESHOLD
private
val
CENTER_PHOTO_BORDER_PX
get
()
=
(
CONST_CENTER_PHOTO_BORDER_PX
*
dens
).
int
private
val
CENTER_HEIGHT_DIFF_PX
get
()
=
(
CONST_CENTER_HEIGHT_DIFF_PX
*
dens
).
int
private
val
HEIGHT_MARGIN_BORDER_PX
get
()
=
(
CONST_HEIGHT_MARGIN_BORDER_PX
*
dens
).
int
private
val
DIFF_BORDER_PX
get
()
=
(
CONST_DIFF_BORDER_PX
*
dens
).
int
private
val
DECAY_TIMER
get
()
=
CONST_DECAY_TIMER
private
var
isDirty
=
true
var
isStopped
=
false
private
var
width
=
0
private
var
height
=
0
private
var
bmpCache
:
MutableList
<
Bitmap
?>
=
mutableListOf
()
private
var
holdIndex
=
0
get
()
=
if
(
isDragging
)
field
else
currentIndex
private
var
currentIndex
:
Int
=
0
set
(
value
)
{
Timber
.
w
(
"currentIndex to: $value"
);
field
=
value
}
private
var
bmpCacheUrls
:
List
<
String
>
=
arrayListOf
()
fun
setAdapter
(
urls
:
List
<
String
>
)
{
bmpCacheUrls
=
urls
bmpCache
=
MutableList
(
bmpCacheUrls
.
size
)
{
null
}
bmpCacheUrls
.
fetchUrls
()
bordersArray
=
IntArray
(
bmpCacheUrls
.
size
*
4
)
cropArray
=
IntArray
(
bmpCacheUrls
.
size
*
4
)
}
private
fun
List
<
String
>.
fetchUrls
(){
this
.
forEachIndexed
{
index
,
s
->
if
(
bmpCache
.
getOrNull
(
index
)
==
null
){
Timber
.
d
(
"loading: $s"
)
Glide
.
with
(
context
)
.
asBitmap
()
.
load
(
bmpCacheUrls
[
index
])
.
apply
(
RequestOptions
().
override
(
width
/
bmpCache
.
size
,
height
))
.
diskCacheStrategy
(
DiskCacheStrategy
.
ALL
)
.
into
(
object
:
CustomTarget
<
Bitmap
>(){
override
fun
onLoadCleared
(
placeholder
:
Drawable
?)
{
Timber
.
d
(
" onLoadCleared "
)
bmpCache
[
index
]
=
null
}
override
fun
onResourceReady
(
resource
:
Bitmap
,
transition
:
Transition
<
in
Bitmap
>?
)
{
Timber
.
d
(
" onResourceReady $resource"
)
bmpCache
[
index
]
=
resource
}
})
}
}
}
fun
setIndex
(
index
:
Int
){
if
(!
isDragging
)
holdIndex
=
index
currentIndex
=
index
isDirty
=
true
}
private
var
bordersArray
:
IntArray
?
=
null
private
var
cropArray
:
IntArray
?
=
null
private
fun
IntArray
.
getPosition
(
dir
:
Float
):
Int
{
if
(
dir
<
0
&&
this
.
getX
(
currentIndex
)
>
width
/
2f
)
return
(
currentIndex
-
1
).
coerceIn
(
0
,
this
.
size
/
4
-
1
)
if
(
dir
>
0
&&
this
.
getRight
(
currentIndex
)
<
width
/
2f
)
return
(
currentIndex
+
1
).
coerceIn
(
0
,
this
.
size
/
4
-
1
)
return
currentIndex
}
private
fun
IntArray
.
getX
(
index
:
Int
)
=
if
(
index
>=
0
)
this
[
index
*
4
+
0
]
else
0
private
fun
IntArray
.
getY
(
index
:
Int
)
=
this
[
index
*
4
+
1
]
private
fun
IntArray
.
getRight
(
index
:
Int
)
=
if
(
index
>=
0
)
this
[
index
*
4
+
2
]
else
0
private
fun
IntArray
.
getBottom
(
index
:
Int
)
=
this
[
index
*
4
+
3
]
private
fun
IntArray
.
getWidth
(
index
:
Int
)
=
this
[
index
*
4
+
2
]
-
this
[
index
*
4
+
0
]
private
fun
IntArray
.
getHeight
(
index
:
Int
)
=
this
[
index
*
4
+
3
]
-
this
[
index
*
4
+
1
]
private
fun
IntArray
.
aspect
(
index
:
Int
)
=
this
.
getWidth
(
index
).
toFloat
()/
this
.
getHeight
(
index
).
toFloat
()
private
fun
IntArray
.
setX
(
index
:
Int
,
block
:()->
Int
){
this
[
index
*
4
+
0
]
=
block
.
invoke
()
}
private
fun
IntArray
.
setY
(
index
:
Int
,
block
:()->
Int
){
this
[
index
*
4
+
1
]
=
block
.
invoke
()
}
private
fun
IntArray
.
setRight
(
index
:
Int
,
block
:()->
Int
){
this
[
index
*
4
+
2
]
=
block
.
invoke
()
}
private
fun
IntArray
.
setBottom
(
index
:
Int
,
block
:()->
Int
){
this
[
index
*
4
+
3
]
=
block
.
invoke
()
}
private
val
Bitmap
.
aspect
:
Float
get
()
=
this
.
width
.
toFloat
()/
this
.
height
.
toFloat
()
private
fun
calcBorders
()
{
val
centerX
=
width
/
2f
-
scrollOffset
val
adjWidth
=
height
*
.
6f
bmpCache
.
forEachIndexed
{
index
,
bitmap
->
val
limit
=
(
2
-
(
index
-
currentIndex
).
absoluteValue
).
coerceIn
(
0
,
1
)
val
direction
=
(
index
-
currentIndex
).
sign
//cos(((index-currentIndex).sign)*1.57f)
val
ch2
=
limit
*
(
(
slidePosition
*
direction
).
coerceIn
(
0f
,
1f
)
+
(
1f
-
direction
.
absoluteValue
)
*
(
1f
-
slidePosition
.
absoluteValue
)
)
bordersArray
?.
let
{
arr
->
val
wDiff
=
height
*
(
bitmap
?.
aspect
?:
0f
)
val
_width
=
adjWidth
+
dragKoef
*((
wDiff
-
adjWidth
)
/
2f
+
CENTER_PHOTO_BORDER_PX
)
*
ch2
arr
.
setX
(
index
)
{
arr
.
getRight
(
index
-
1
)
}
arr
.
setRight
(
index
)
{(
arr
.
getX
(
index
)
+
_width
).
int
}
arr
.
setY
(
index
)
{(
HEIGHT_MARGIN_BORDER_PX
+
CENTER_HEIGHT_DIFF_PX
*
(
1f
-
ch2
)).
int
}
arr
.
setBottom
(
index
)
{
height
-
(
HEIGHT_MARGIN_BORDER_PX
+
CENTER_HEIGHT_DIFF_PX
*
(
1f
-
ch2
)).
int
}
}
cropArray
?.
let
{
arr
->
val
asp
=
bordersArray
?.
aspect
(
index
)
?:
0f
bitmap
?.
let
{
if
(
asp
>=
it
.
aspect
)
{
arr
.
setX
(
index
)
{
0
}
arr
.
setRight
(
index
)
{
it
.
width
}
val
hKef
=
it
.
aspect
/
asp
val
marg
=
it
.
height
*
(
1f
-
hKef
)
/
2f
arr
.
setY
(
index
)
{
marg
.
int
}
arr
.
setBottom
(
index
)
{
it
.
height
-
marg
.
int
}
}
else
{
arr
.
setY
(
index
)
{
0
}
arr
.
setBottom
(
index
)
{
it
.
height
}
val
hKef
=
asp
/
it
.
aspect
val
marg
=
it
.
width
*
(
1f
-
hKef
)
/
2f
arr
.
setX
(
index
)
{
marg
.
int
}
arr
.
setRight
(
index
)
{
it
.
width
-
marg
.
int
}
}
}
}
}
bordersArray
?.
let
{
arr
->
val
halfW
=
arr
.
getWidth
(
currentIndex
)
/
2f
val
minusW
=
arr
.
getX
(
holdIndex
)
-
centerX
+
halfW
*
(
1f
+
2f
*
slidePosition
)
bmpCache
.
forEachIndexed
{
index
,
bitmap
->
val
limit
=
(
2
-
(
index
-
currentIndex
).
absoluteValue
).
coerceIn
(
0
,
1
)
val
direction
=
(
index
-
currentIndex
).
sign
val
cBorder
=
(
CENTER_PHOTO_BORDER_PX
)
val
borderKoef
=
(
direction
+
1f
-
limit
*
sin
((
direction
+
slidePosition
.
sign
).
coerceIn
(-
1f
,
1f
)
*
1.57f
)
*
slidePosition
.
absoluteValue
)
val
borderSize
=
dragKoef
*
cBorder
*
borderKoef
arr
.
setX
(
index
)
{(
arr
.
getX
(
index
)
-
minusW
.
int
+
borderSize
+
DIFF_BORDER_PX
).
int
}
arr
.
setRight
(
index
)
{
(
arr
.
getRight
(
index
)
-
minusW
.
int
+
borderSize
-
DIFF_BORDER_PX
).
int
}
}
}
}
private
val
Float
.
int
:
Int
get
()
{
return
this
.
toInt
()}
fun
perfomDrag
(
distanceX
:
Float
?,
dragging
:
Boolean
=
true
){
isDragging
=
dragging
if
(
isDragging
)
distanceX
?.
let
{
perfomScroll
(
it
)}
else
{
holdIndex
=
currentIndex
scrollOffset
=
0f
touchOffset
=
0f
}
isDirty
=
true
}
private
fun
perfomScroll
(
distanceX
:
Float
)
{
touchOffset
+=
distanceX
*
scrollScaleFactor
val
p
=
bordersArray
?.
getPosition
(
distanceX
.
sign
)
?:
0
if
(
p
!=
currentIndex
)
{
setIndex
(
p
)
onChangePage
?.
invoke
(
p
)
}
isDirty
=
true
}
var
onChangePage
:
((
newPage
:
Int
)->
Unit
)?
=
null
private
var
scrollScaleFactor
=
1f
private
var
touchOffset
=
0f
private
var
scrollOffset
=
0f
private
var
isDragging
=
false
private
var
slidePosition
=
0f
private
var
dragKoef
=
1f
fun
setSlidePosition
(
newPosition
:
Float
){
slidePosition
=
newPosition
isDirty
=
true
}
private
var
decayFraction
=
0f
private
fun
timerDecay
(
mills
:
Long
){
isDirty
=
true
decayFraction
+=
mills
animateBorders
()
scrollOffset
=
scrollOffset
.
smoothLerp
(
touchOffset
-
scrollOffset
,.
2f
)
if
(
touchOffset
>
0
&&
scrollOffset
>=
touchOffset
)
{
scrollOffset
=
touchOffset
isDirty
=
false
}
else
if
(
touchOffset
<
0
&&
scrollOffset
<=
touchOffset
)
{
scrollOffset
=
touchOffset
isDirty
=
false
}
if
(
decayFraction
>
DECAY_TIMER
)
isDirty
=
false
val
dirty
=
animateBorders
()
if
(!
isDirty
)
isDirty
=
dirty
}
private
fun
animateBorders
():
Boolean
{
if
(
isDragging
&&
dragKoef
>
0
){
dragKoef
=
dragKoef
.
smoothLerp
(-
dragKoef
,.
12f
)
if
(
dragKoef
<.
1f
)
dragKoef
=
0f
return
dragKoef
>
0
}
if
(!
isDragging
&&
dragKoef
<
1f
)
{
dragKoef
=
dragKoef
.
smoothLerp
(
1f
-
dragKoef
,.
03f
)
if
(
dragKoef
>.
99f
)
dragKoef
=
1f
return
dragKoef
<
1f
}
return
false
}
private
fun
Float
.
smoothLerp
(
delta
:
Float
,
fraction
:
Float
=.
4f
):
Float
{
return
this
+
fraction
*
(
delta
)
}
fun
setSize
(
w
:
Int
,
h
:
Int
){
width
=
w
height
=
h
}
override
fun
run
()
{
super
.
run
()
Timber
.
w
(
"isStopped: $isStopped"
)
Timber
.
w
(
"isDirty: $isDirty"
)
isDirty
=
true
while
(!
isStopped
)
{
while
(!
isDirty
)
sleep
(
SLEEP_THRESHOLD
)
// in real life this sleep is more complicated
isDirty
=
false
val
surf
=
Surface
(
surface
)
val
dRect
=
Rect
(
width
.
div
(
4
)
+
width
.
div
(
2
)
,
HEIGHT_MARGIN_BORDER_PX
,
width
-
width
.
div
(
4
)
,
height
.
minus
(
HEIGHT_MARGIN_BORDER_PX
)
)
val
c
=
surf
.
lockCanvas
(
dRect
)
c
.
drawColor
(
Color
.
TRANSPARENT
)
timerDecay
(
SLEEP_THRESHOLD
)
if
(
bmpCache
.
size
>
0
)
calcBorders
()
Timber
.
d
(
"bmpCache ${bmpCache.size}"
)
bmpCache
.
forEachIndexed
{
index
,
bitmap
->
// Timber.d("bitmap ${bitmap} / $index")
bitmap
?.
let
{
val
bmpX
=
cropArray
?.
getX
(
index
)
?:
0
val
bmpY
=
cropArray
?.
getY
(
index
)
?:
0
val
bmpRight
=
cropArray
?.
getRight
(
index
)
?:
0
val
bmpBottom
=
cropArray
?.
getBottom
(
index
)
?:
0
val
dstX
=
bordersArray
?.
getX
(
index
)
?:
0
val
dstY
=
bordersArray
?.
getY
(
index
)
?:
0
val
dstRight
=
bordersArray
?.
getRight
(
index
)
?:
0
val
dstBottom
=
bordersArray
?.
getBottom
(
index
)
?:
0
c
.
drawBitmap
(
it
,
Rect
(
bmpX
,
bmpY
,
bmpRight
,
bmpBottom
)
,
Rect
(
dstX
,
dstY
,
dstRight
,
dstBottom
)
,
null
)
}
}
surf
.
unlockCanvasAndPost
(
c
)
surf
.
release
()
// isDirty = false
}
Timber
.
w
(
"STOPPED; $isStopped"
)
Timber
.
w
(
"STOPPED; $isDirty"
)
isDirty
=
false
}
private
fun
calcHeightPixel
(
index
:
Int
,
selectedIndex
:
Int
):
Int
{
return
height
}
private
fun
calcWidthPixel
(
index
:
Int
,
selectedIndex
:
Int
):
Int
{
val
dist
=
abs
(
index
-
selectedIndex
)
val
bled
=
index
-
selectedIndex
// Timber.d("gonna calc: $bled")
try
{
var
bled_res
=
100
;
// Timber.d("res is : $bled_res")
if
(
bled
==
0
)
bled_res
=
calcHeightPixel
(
index
,
selectedIndex
)
else
bled_res
=
(
calcHeightPixel
(
index
,
selectedIndex
)*
(
1f
-
.
05f
*
dist
)).
int
bled_res
=
when
(
bled
)
{
0
->
calcHeightPixel
(
index
,
selectedIndex
)
in
-
1
downTo
Int
.
MIN_VALUE
->
(
calcHeightPixel
(
index
,
selectedIndex
)*
(
1f
-
.
05f
*
dist
)).
int
in
1
..
Int
.
MAX_VALUE
->
(
calcHeightPixel
(
index
,
selectedIndex
)*
(
1f
-
.
05f
*
dist
)).
int
else
->
error
(
"Unexeptable value"
)
}
// Timber.d("res is : $bled_res")
return
bled_res
}
catch
(
e
:
Exception
){
Timber
.
e
(
e
)}
return
-
1
}
private
fun
Bitmap
.
flip
():
Bitmap
{
val
flip
=
Matrix
()
flip
.
postScale
(
1f
,
-
1f
)
return
Bitmap
.
createBitmap
(
this
,
0
,
0
,
this
.
width
,
this
.
height
,
flip
,
true
)
}
}
app/src/main/res/layout/photo_view_screen.xml
View file @
c6397e8d
...
...
@@ -67,12 +67,14 @@
app:layout_constraintTop_toTopOf=
"@+id/guideline2"
app:srcCompat=
"@drawable/iic_full_view"
/>
<androidx.recyclerview.widget.RecyclerView
<com.biganto.visual.roompark.presentation.screen.photo.util.PhotoPreviewSlider
android:id=
"@+id/photosPreviewSlider"
android:layout_width=
"0dp"
android:layout_height=
"0dp"
android:layout_marginTop=
"8dp"
android:layout_marginBottom=
"16dp"
android:orientation=
"horizontal"
android:visibility=
"invisible"
app:layout_constraintBottom_toBottomOf=
"parent"
app:layout_constraintEnd_toStartOf=
"@+id/change_size_button"
app:layout_constraintStart_toEndOf=
"@+id/show_full_button"
...
...
dependencies.gradle
View file @
c6397e8d
...
...
@@ -26,4 +26,5 @@ ext {
exoPlayerVersion
=
"2.10.8"
photoViewVersion
=
"2.0.0"
viewPager2Version
=
"1.0.0"
glideVersion
=
"4.11.0"
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment