Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
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
Hide 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