Commit b34275dc authored by Vladislav Bogdashkin's avatar Vladislav Bogdashkin 🎣

Merge branch 'develop' into feature/read_flag

parents 9e7809d1 68531f19
...@@ -18,6 +18,7 @@ import com.biganto.visual.roompark.domain.model.AlbumPreviewModel ...@@ -18,6 +18,7 @@ import com.biganto.visual.roompark.domain.model.AlbumPreviewModel
import com.biganto.visual.roompark.domain.model.PhotoModel import com.biganto.visual.roompark.domain.model.PhotoModel
import com.biganto.visual.roompark.presentation.screen.albums.util.AlbumListAdapter import com.biganto.visual.roompark.presentation.screen.albums.util.AlbumListAdapter
import com.biganto.visual.roompark.presentation.screen.albums.util.AlbumsHeaderAdapter import com.biganto.visual.roompark.presentation.screen.albums.util.AlbumsHeaderAdapter
import com.biganto.visual.roompark.presentation.screen.albums.util.BubbleSlider
import com.biganto.visual.roompark.presentation.screen.photo.PhotoScreenController import com.biganto.visual.roompark.presentation.screen.photo.PhotoScreenController
import com.biganto.visual.roompark.util.view_utils.grid.CeilsDecoration import com.biganto.visual.roompark.util.view_utils.grid.CeilsDecoration
import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.RouterTransaction
...@@ -63,6 +64,8 @@ class AlbumsScreenController : ...@@ -63,6 +64,8 @@ class AlbumsScreenController :
@BindView(R.id.header_album_title) @BindView(R.id.header_album_title)
lateinit var currentAlbomTitle: MaterialTextView lateinit var currentAlbomTitle: MaterialTextView
@BindView(R.id.bubble_slider)
lateinit var bubble: BubbleSlider
// //
...@@ -96,6 +99,10 @@ class AlbumsScreenController : ...@@ -96,6 +99,10 @@ class AlbumsScreenController :
, resources?.getDimensionPixelSize(R.dimen.ceil_grid_padding)) , resources?.getDimensionPixelSize(R.dimen.ceil_grid_padding))
) )
bubble.setUpView(headersRecyclerView)
albumsRecyclerView.isNestedScrollingEnabled = false albumsRecyclerView.isNestedScrollingEnabled = false
albumsRecyclerView.layoutManager = albumsRecyclerView.layoutManager =
LinearLayoutManager(activity, RecyclerView.VERTICAL, false) LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
...@@ -164,11 +171,12 @@ class AlbumsScreenController : ...@@ -164,11 +171,12 @@ class AlbumsScreenController :
viewState.list.asSequence().sortedByDescending { it.published }.toList() viewState.list.asSequence().sortedByDescending { it.published }.toList()
) )
headersRecyclerView.let { (headersRecyclerView.adapter as AlbumsHeaderAdapter)
it.scrollToPosition( .getItemPosition(viewState.selectedAlbumId)
(it.adapter as AlbumsHeaderAdapter).getItemPosition(viewState.selectedAlbumId) .let {
) headersRecyclerView.smoothScrollToPosition(it)
} bubble.onCurrentItemChanged(it)
}
viewState.list.first { it.albumId == viewState.selectedAlbumId }.let { viewState.list.first { it.albumId == viewState.selectedAlbumId }.let {
currentAlbomTitle.text = it.title currentAlbomTitle.text = it.title
...@@ -180,9 +188,11 @@ class AlbumsScreenController : ...@@ -180,9 +188,11 @@ class AlbumsScreenController :
private fun render(viewState: AlbumsScreenViewState.HeaderAlbumChoosed) { private fun render(viewState: AlbumsScreenViewState.HeaderAlbumChoosed) {
(headersRecyclerView.adapter as AlbumsHeaderAdapter) (headersRecyclerView.adapter as AlbumsHeaderAdapter)
.getItemPosition(viewState.item.albumId).let { .getItemPosition(viewState.item.albumId)
headersRecyclerView.scrollToPosition(it) .let {
} headersRecyclerView.smoothScrollToPosition(it)
bubble.onCurrentItemChanged(it)
}
currentAlbomTitle.text = viewState.item.title currentAlbomTitle.text = viewState.item.title
activity?.let { ctx -> activity?.let { ctx ->
...@@ -206,11 +216,12 @@ class AlbumsScreenController : ...@@ -206,11 +216,12 @@ class AlbumsScreenController :
viewState.restore.albumsPreview.asSequence().sortedByDescending { it.published }.toList() viewState.restore.albumsPreview.asSequence().sortedByDescending { it.published }.toList()
) )
headersRecyclerView.let { (headersRecyclerView.adapter as AlbumsHeaderAdapter)
it.scrollToPosition( .getItemPosition(viewState.restore.currentIndex)
(it.adapter as AlbumsHeaderAdapter).getItemPosition(viewState.restore.currentIndex) .let {
) headersRecyclerView.smoothScrollToPosition(it)
} bubble.onCurrentItemChanged(it)
}
viewState.restore.albumsPreview.first { it.albumId == viewState.restore.currentIndex } viewState.restore.albumsPreview.first { it.albumId == viewState.restore.currentIndex }
.let { .let {
......
package com.biganto.visual.roompark.presentation.screen.albums.util
import android.content.Context
import android.graphics.SurfaceTexture
import android.util.AttributeSet
import android.view.TextureView
import androidx.recyclerview.widget.RecyclerView
import timber.log.Timber
/**
* Created by Vladislav Bogdashkin on 22.12.2019.
*/
class BubbleSlider @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : TextureView(context, attrs, defStyleAttr)
,TextureView.SurfaceTextureListener{
private var texThread: RendererThread?=null
private var recyclerView:RecyclerView? = null
private var actualPosition = -1
private fun invalidatePosition(){
val child = recyclerView?.findViewHolderForAdapterPosition(actualPosition)
if (child == null) texThread?.setCenter(-9999)
else texThread?.setCenter(child.itemView.x.toInt()+child.itemView.width/ 2)
}
fun setUpView(view:RecyclerView) {
recyclerView = view
recyclerView?.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
invalidatePosition()
}
}
fun onCurrentItemChanged(newPosition:Int){
actualPosition = newPosition
invalidatePosition()
texThread?.setIndex(actualPosition)
}
fun processSliding(_position:Float){
texThread?.setSlidePosition(_position)
}
init {
surfaceTextureListener=this
}
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?.start()
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
texThread?.isStopped=true
}
}
package com.biganto.visual.roompark.presentation.screen.albums.util
import android.content.Context
import android.graphics.*
import android.view.Surface
import com.biganto.visual.roompark.R
import timber.log.Timber
import kotlin.math.absoluteValue
import kotlin.math.tan
/**
* Created by Vladislav Bogdashkin on 18.07.2019.
*/
private const val CONST_SLEEP_THRESHOLD = 6L
private const val CONST_HEIGHT_MARGIN_BORDER_PX = 8
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 HEIGHT_MARGIN_BORDER_PX get() =
(CONST_HEIGHT_MARGIN_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 centerX = 0
private var destCenterX = 0
private var holdIndex = 0
get() = if (isDragging) field
else currentIndex
private var currentIndex:Int = 0
set(value) {Timber.w("currentIndex to: $value");field = value}
fun setIndex(index:Int){
if (!isDragging) holdIndex = index
currentIndex = index
isDirty=true
}
private val Float.int:Int get() {return this.toInt()}
fun setCenter(centerX:Int){
this.centerX = centerX
Timber.w("CENTER IS: $centerX")
isDirty = true
}
private var isDragging = false
private var slidePosition = 0f
fun setSlidePosition(newPosition:Float){
slidePosition = newPosition
isDirty = true
}
private var decayFraction = 0f
private fun timerDecay(mills:Long){
isDirty=true
decayFraction+=mills
if (decayFraction> DECAY_TIMER) isDirty=false
val dirty = centerSmooth()
if (!isDirty) isDirty = dirty
}
private fun centerSmooth():Boolean{
centerX = centerX.smoothLerp(destCenterX-centerX,decayFraction/DECAY_TIMER)
Timber.w("CENTER visa verse: $centerX -> $destCenterX")
return (centerX - destCenterX).absoluteValue>1
}
private fun Float.smoothLerp( delta: Float, fraction:Float =.4f): Float {
return this + fraction * (delta)
}
private fun Int.smoothLerp( delta: Int, fraction:Float =.4f): Int {
return (this + fraction * (delta)).int
}
fun setSize(w: Int, h: Int){
width=w
height=h
}
private val pinColor:Int by lazy {
context.resources.getColor(R.color.colorOpacityBackground,context.theme)
}
private val trianglePath:Path
get() {
val p = Path()
p.fillType = Path.FillType.EVEN_ODD
p.moveTo(centerX.toFloat(),0f)
p.lineTo(centerX.toFloat() + height*tan(Math.toRadians(45.0)).toFloat(),height.toFloat())
p.lineTo(centerX.toFloat() - height*tan(Math.toRadians(45.0)).toFloat(),height.toFloat())
p.lineTo(centerX.toFloat(),0f)
p.close()
return p
}
private val trianglePaint:Paint by lazy {
val p = Paint()
p.color = pinColor
p.style = Paint.Style.FILL_AND_STROKE
p.isAntiAlias = true
p
}
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(
0
, 0
, width
, height
)
val c = surf.lockCanvas(dRect)
c.drawColor(Color.WHITE)
c.drawPath(trianglePath,trianglePaint)
// c.drawRect(Rect(centerX - 30,height,centerX+30,0),trianglePaint)
// timerDecay(SLEEP_THRESHOLD)
surf.unlockCanvasAndPost(c)
surf.release()
// isDirty = false
}
Timber.w("STOPPED; $isStopped")
Timber.w("STOPPED; $isDirty")
isDirty=false
}
}
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container" android:id="@+id/container"
android:background="@color/colorPrimary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
...@@ -19,6 +20,18 @@ ...@@ -19,6 +20,18 @@
tools:itemCount="1" tools:itemCount="1"
tools:listitem="@layout/album_header_preview_viewholder" /> tools:listitem="@layout/album_header_preview_viewholder" />
<com.biganto.visual.roompark.presentation.screen.albums.util.BubbleSlider
android:id="@+id/bubble_slider"
android:layout_width="match_parent"
android:layout_height="16dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/headers_recycler_view"
/>
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
android:id="@+id/photo_albums_container" android:id="@+id/photo_albums_container"
android:layout_width="match_parent" android:layout_width="match_parent"
......
...@@ -2,7 +2,7 @@ ext { ...@@ -2,7 +2,7 @@ ext {
$APPLICATION_ID = "com.biganto.visual.roompark" $APPLICATION_ID = "com.biganto.visual.roompark"
targetSdkVersion_RoomPark = 28 targetSdkVersion_RoomPark = 28
minSdkVersion_RoomPark = 21 minSdkVersion_RoomPark = 23
compileSdkVersion_RoomPark = 28 compileSdkVersion_RoomPark = 28
VERSION_CODE = 1 VERSION_CODE = 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment