Commit 23fc8814 authored by Vladislav Bogdashkin's avatar Vladislav Bogdashkin 🎣

Merge branch 'feature/photo_scroller' into develop

parents 88c6ccf6 adfcf8c4
<component name="ProjectCodeStyleConfiguration"> <component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173"> <code_scheme name="Project" version="173">
<AndroidXmlCodeStyleSettings>
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings> <JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings> </JetCodeStyleSettings>
......
...@@ -152,9 +152,18 @@ dependencies { ...@@ -152,9 +152,18 @@ dependencies {
implementation "com.google.android.exoplayer:exoplayer-hls:$exoPlayerVersion" implementation "com.google.android.exoplayer:exoplayer-hls:$exoPlayerVersion"
implementation "com.google.android.exoplayer:extension-rtmp:$exoPlayerVersion" implementation "com.google.android.exoplayer:extension-rtmp:$exoPlayerVersion"
//ViewPager2
implementation "androidx.viewpager2:viewpager2:$viewPager2Version"
//Photo view //Photo view
implementation "com.github.chrisbanes:PhotoView:$photoViewVersion" implementation "com.github.chrisbanes:PhotoView:$photoViewVersion"
//Glide
implementation "com.github.bumptech.glide:glide:$glideVersion"
annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion"
//Tests //Tests
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test:runner:1.2.0'
......
...@@ -22,6 +22,8 @@ import com.biganto.visual.roompark.presentation.screen.photo.PhotoScreenControll ...@@ -22,6 +22,8 @@ import com.biganto.visual.roompark.presentation.screen.photo.PhotoScreenControll
import com.biganto.visual.roompark.util.extensions.scaleCenterCrop import com.biganto.visual.roompark.util.extensions.scaleCenterCrop
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
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler
import com.google.android.material.textview.MaterialTextView import com.google.android.material.textview.MaterialTextView
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import io.reactivex.Observable import io.reactivex.Observable
...@@ -140,6 +142,7 @@ class AlbumsScreenController : ...@@ -140,6 +142,7 @@ class AlbumsScreenController :
is AlbumsScreenViewState.HeaderAlbumChoosed-> render(viewState) is AlbumsScreenViewState.HeaderAlbumChoosed-> render(viewState)
is AlbumsScreenViewState.PhotoSelected -> render(viewState) is AlbumsScreenViewState.PhotoSelected -> render(viewState)
is AlbumsScreenViewState.SomeError -> render(viewState) is AlbumsScreenViewState.SomeError -> render(viewState)
is AlbumsScreenViewState.RestoreView -> render(viewState)
} }
} }
...@@ -148,7 +151,11 @@ class AlbumsScreenController : ...@@ -148,7 +151,11 @@ class AlbumsScreenController :
} }
private fun render(viewState: AlbumsScreenViewState.PhotoSelected){ private fun render(viewState: AlbumsScreenViewState.PhotoSelected){
router.pushController(RouterTransaction.with(PhotoScreenController(viewState.photoId))) router.pushController(RouterTransaction.with(PhotoScreenController(viewState.photoId))
.pushChangeHandler(VerticalChangeHandler())
.popChangeHandler(FadeChangeHandler(false))
)
} }
private fun render(viewState: AlbumsScreenViewState.SomeError) = private fun render(viewState: AlbumsScreenViewState.SomeError) =
...@@ -199,6 +206,32 @@ class AlbumsScreenController : ...@@ -199,6 +206,32 @@ class AlbumsScreenController :
) )
} }
private fun render(viewState: AlbumsScreenViewState.RestoreView){
(albumsRecyclerView.adapter as AlbumListAdapter).setItems(
viewState.restore.albumList.asSequence().sortedByDescending { it.published }.toList()
)
(headersRecyclerView.adapter as AlbumsHeaderAdapter).setItems(
viewState.restore.albumsPreview.asSequence().sortedByDescending { it.published }.toList()
)
headersRecyclerView.let {
it.scrollToPosition(
(it.adapter as AlbumsHeaderAdapter).getItemPosition(viewState.restore.currentIndex)
)
}
viewState.restore.albumsPreview.first { it.albumId == viewState.restore.currentIndex}
.let {
currentAlbomTitle.text = it.title
picassoAsync
.load(it.previewUrl)
.transform(BlurTransformation(activity, 13, 2))
.transform(ColorFilterTransformation(0xCC000000.toInt()))
.into(photosBackgroundTarget)
}
}
override fun onAlbumSelected(): Observable<AlbumPreviewModel> override fun onAlbumSelected(): Observable<AlbumPreviewModel>
= (headersRecyclerView.adapter as AlbumsHeaderAdapter) = (headersRecyclerView.adapter as AlbumsHeaderAdapter)
.onItemClicked .onItemClicked
......
...@@ -2,6 +2,8 @@ package com.biganto.visual.roompark.presentation.screen.albums ...@@ -2,6 +2,8 @@ package com.biganto.visual.roompark.presentation.screen.albums
import com.biganto.visual.roompark.conductor.BigantoBasePresenter import com.biganto.visual.roompark.conductor.BigantoBasePresenter
import com.biganto.visual.roompark.domain.interactor.AlbumsInteractor import com.biganto.visual.roompark.domain.interactor.AlbumsInteractor
import com.biganto.visual.roompark.domain.model.AlbumPreviewModel
import com.biganto.visual.roompark.domain.model.AlbumSortedModel
import com.biganto.visual.roompark.util.monades.ExceptionString import com.biganto.visual.roompark.util.monades.ExceptionString
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
...@@ -13,32 +15,35 @@ import javax.inject.Named ...@@ -13,32 +15,35 @@ import javax.inject.Named
* Created by Vladislav Bogdashkin on 30.09.2019. * Created by Vladislav Bogdashkin on 30.09.2019.
*/ */
class AlbumsScreenPresenter @Inject constructor( class AlbumsScreenPresenter @Inject constructor(
private val interactor: AlbumsInteractor private val interactor: AlbumsInteractor
,@Named(SELECTED_ALBUM_INDEX_KEY) private var selectedIndex:Int ,@Named(SELECTED_ALBUM_INDEX_KEY) private var selectedIndex:Int
) )
: BigantoBasePresenter<AlbumsScreen, AlbumsScreenViewState>() { : BigantoBasePresenter<AlbumsScreen, AlbumsScreenViewState>() {
private var restoreModel = RestoreModel(listOf(), listOf(),selectedIndex)
override fun defaultErrorViewStateHandler() = override fun defaultErrorViewStateHandler() =
{e: ExceptionString -> AlbumsScreenViewState.SomeError(e) } {e: ExceptionString -> AlbumsScreenViewState.SomeError(e) }
private fun requestAlbum(id:Int):Observable<AlbumsScreenViewState> = private fun requestAlbum(id:Int):Observable<AlbumsScreenViewState> =
interactor.fetchAlbumPhotos(id) interactor.fetchAlbumPhotos(id)
.filter { !it.isNullOrEmpty() } .filter { !it.isNullOrEmpty() }
.doOnNext{ restoreModel.albumList = it }
.map { AlbumsScreenViewState.AlbumsSelected(it)} .map { AlbumsScreenViewState.AlbumsSelected(it)}
override fun bindIntents() { override fun bindIntents() {
val fetchParents = interactor.fetchHeaderAlbums() val fetchParents = interactor.fetchHeaderAlbums()
.filter { !it.isNullOrEmpty() } .filter { !it.isNullOrEmpty() }
.doOnNext{ restoreModel.albumsPreview = it }
.map { AlbumsScreenViewState.AlbumsListLoaded(it, selectedIndex) } .map { AlbumsScreenViewState.AlbumsListLoaded(it, selectedIndex) }
val fetchSelected = requestAlbum(selectedIndex) val fetchSelected = requestAlbum(selectedIndex)
val headerItemSelected = intent(AlbumsScreen::onAlbumSelected) val headerItemSelected = intent(AlbumsScreen::onAlbumSelected)
.doOnNext { selectedIndex = it.albumId } .doOnNext { selectedIndex = it.albumId }
.doOnNext { restoreModel.currentIndex = it.albumId }
.flatMap<AlbumsScreenViewState> { model -> .flatMap<AlbumsScreenViewState> { model ->
requestAlbum(model.albumId) requestAlbum(model.albumId)
.startWith(Observable.just(AlbumsScreenViewState.HeaderAlbumChoosed(item = model))) .startWith(Observable.just(AlbumsScreenViewState.HeaderAlbumChoosed(item = model)))
...@@ -47,9 +52,6 @@ class AlbumsScreenPresenter @Inject constructor( ...@@ -47,9 +52,6 @@ class AlbumsScreenPresenter @Inject constructor(
val photoSelected = intent(AlbumsScreen::onPhotoSelected) val photoSelected = intent(AlbumsScreen::onPhotoSelected)
.map { AlbumsScreenViewState.PhotoSelected(it.photoId) } .map { AlbumsScreenViewState.PhotoSelected(it.photoId) }
val state = restoreStateObservable val state = restoreStateObservable
.mergeWith(fetchParents) .mergeWith(fetchParents)
.mergeWith(fetchSelected) .mergeWith(fetchSelected)
...@@ -60,4 +62,12 @@ class AlbumsScreenPresenter @Inject constructor( ...@@ -60,4 +62,12 @@ class AlbumsScreenPresenter @Inject constructor(
subscribeViewState(state.cast(AlbumsScreenViewState::class.java), AlbumsScreen::render) subscribeViewState(state.cast(AlbumsScreenViewState::class.java), AlbumsScreen::render)
} }
override fun detachView() {
super.detachView()
restoreStateObservable.accept(AlbumsScreenViewState.RestoreView(restoreModel))
}
} }
data class RestoreModel(var albumList:List<AlbumSortedModel>
,var albumsPreview:List<AlbumPreviewModel>
, var currentIndex:Int)
\ No newline at end of file
...@@ -17,4 +17,5 @@ sealed class AlbumsScreenViewState : BigantoBaseViewState() { ...@@ -17,4 +17,5 @@ sealed class AlbumsScreenViewState : BigantoBaseViewState() {
class HeaderAlbumChoosed(val item:AlbumPreviewModel) : AlbumsScreenViewState() class HeaderAlbumChoosed(val item:AlbumPreviewModel) : AlbumsScreenViewState()
class PhotoSelected(val photoId:Int) : AlbumsScreenViewState() class PhotoSelected(val photoId:Int) : AlbumsScreenViewState()
class SomeError(val exception: ExceptionString) : AlbumsScreenViewState() class SomeError(val exception: ExceptionString) : AlbumsScreenViewState()
class RestoreView(val restore:RestoreModel) : AlbumsScreenViewState()
} }
\ No newline at end of file
...@@ -10,8 +10,6 @@ import com.biganto.visual.roompark.base.RoomParkApplication ...@@ -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.AlbumSortedModel
import com.biganto.visual.roompark.domain.model.PhotoModel import com.biganto.visual.roompark.domain.model.PhotoModel
import com.biganto.visual.roompark.domain.model.PhotoResolutionModel 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.CommonRecyclerAdapter
import com.biganto.visual.roompark.presentation.screen.settings.util.CommonViewHolder import com.biganto.visual.roompark.presentation.screen.settings.util.CommonViewHolder
import com.biganto.visual.roompark.util.view_utils.image_view.RoundedImageView import com.biganto.visual.roompark.util.view_utils.image_view.RoundedImageView
......
...@@ -9,7 +9,8 @@ import com.biganto.visual.roompark.R ...@@ -9,7 +9,8 @@ import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.base.RoomParkApplication import com.biganto.visual.roompark.base.RoomParkApplication
import com.biganto.visual.roompark.base.RoomParkMainActivity import com.biganto.visual.roompark.base.RoomParkMainActivity
import com.biganto.visual.roompark.conductor.BigantoBaseController 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.google.android.material.textview.MaterialTextView
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import timber.log.Timber import timber.log.Timber
...@@ -39,11 +40,26 @@ class PhotoScreenController : ...@@ -39,11 +40,26 @@ class PhotoScreenController :
@BindView(R.id.photo_frame) @BindView(R.id.photo_frame)
lateinit var photoViewPager: ViewPager2 lateinit var photoViewPager: ViewPager2
@BindView(R.id.photosPreviewSlider)
lateinit var slider: PhotoPreviewSlider
private fun bindRecycler() { private fun bindRecycler() {
photoViewPager.isNestedScrollingEnabled = false photoViewPager.isNestedScrollingEnabled = false
photoViewPager.offscreenPageLimit = 2 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) { override fun onViewBound(v: View) {
...@@ -68,8 +84,7 @@ class PhotoScreenController : ...@@ -68,8 +84,7 @@ class PhotoScreenController :
fun getComponent() = DaggerPhotoScreenComponent.factory() fun getComponent() = DaggerPhotoScreenComponent.factory()
.create(RoomParkApplication.component .create(RoomParkApplication.component
,activity as RoomParkMainActivity ,activity as RoomParkMainActivity
,args.getInt(SELECTED_PHOTO_KEY)) ,args.getInt(SELECTED_PHOTO_KEY)).inject(this)
.inject(this)
override fun render(viewState: PhotoScreenViewState) { override fun render(viewState: PhotoScreenViewState) {
Timber.d("render: $viewState") Timber.d("render: $viewState")
...@@ -94,11 +109,15 @@ class PhotoScreenController : ...@@ -94,11 +109,15 @@ class PhotoScreenController :
lateinit var picassoAsync:Picasso lateinit var picassoAsync:Picasso
private fun render(viewState: PhotoScreenViewState.PhotoListLoaded) { private fun render(viewState: PhotoScreenViewState.PhotoListLoaded) {
(photoViewPager.adapter as PhotoViewerAdapter).setItems( (photoViewPager.adapter as PhotosAdapter).setItems(
viewState.list.asSequence().sortedBy{it.sort}.toList() viewState.list.asSequence().sortedBy{it.sort}.toList()
) )
photoViewPager.currentItem = (photoViewPager.adapter as PhotoViewerAdapter)
.getItemPosition(viewState.selectedId) slider.visibility= View.VISIBLE
slider.setUpViewPager(photoViewPager)
photoViewPager.currentItem =
(photoViewPager.adapter as PhotosAdapter).indexById(viewState.selectedId)
} }
private fun render(viewState: PhotoScreenViewState.AldumFetched) { private fun render(viewState: PhotoScreenViewState.AldumFetched) {
...@@ -107,13 +126,14 @@ class PhotoScreenController : ...@@ -107,13 +126,14 @@ class PhotoScreenController :
private fun render(viewState: PhotoScreenViewState.PhotoFetched){ private fun render(viewState: PhotoScreenViewState.PhotoFetched){
(photoViewPager.adapter as PhotoViewerAdapter).setItems(arrayListOf(viewState.model)) (photoViewPager.adapter as PhotosAdapter).setItems(arrayListOf(viewState.model))
} }
private fun render(viewState: PhotoScreenViewState.PhotoSelected){ private fun render(viewState: PhotoScreenViewState.PhotoSelected){
// (photoViewPager.adapter as PhotoViewerAdapter).setItems(arrayListOf(viewState.model)) // (photoViewPager.adapter as PhotoViewerAdapter).setItems(arrayListOf(viewState.model))
} }
override fun handleBack(): Boolean {router.popController(this); return true}
override fun getLayoutId(): Int = R.layout.photo_view_screen override fun getLayoutId(): Int = R.layout.photo_view_screen
......
...@@ -45,4 +45,11 @@ class PhotoScreenPresenter @Inject constructor( ...@@ -45,4 +45,11 @@ class PhotoScreenPresenter @Inject constructor(
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
subscribeViewState(state.cast(PhotoScreenViewState::class.java), PhotoScreen::render) subscribeViewState(state.cast(PhotoScreenViewState::class.java), PhotoScreen::render)
} }
override fun detachView() {
super.detachView()
restoreStateObservable.accept(PhotoScreenViewState.Idle())
}
} }
\ No newline at end of file
package com.biganto.visual.roompark.presentation.screen.photo.util
import android.view.View
import butterknife.BindView
import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.base.RoomParkApplication
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
/**
* Created by Vladislav Bogdashkin on 16.10.2019.
*/
class PhotosAdapter : CommonRecyclerAdapter<PhotosViewHolder, PhotoModel>() {
override val vhKlazz = PhotosViewHolder::class
override fun getVhLayout(): Int = R.layout.photo_preview_viewholder
}
class PhotosViewHolder(itemView: View) : CommonViewHolder<PhotoModel>(itemView) {
@BindView(R.id.photo_preview_imageview) lateinit var photoPreview: RoundedImageView
private val picassoAsync by lazy {
return@lazy RoomParkApplication.component.providePicassoAsync()
}
override fun onViewBound(model: PhotoModel) {
model.resolutionList.lowelest()?.let {
picassoAsync
.load(it.url)
.centerCrop()
.fit()
.into(photoPreview)
}}
}
fun List<PhotoResolutionModel>.lowelest() =
this.minBy { it.resWidth * it.resHeight }
\ No newline at end of file
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(vp?.currentItem?:0)
// texThread?.setIndex(min(_l.size,2))
}?: error("adapter not ready!")
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
texThread?.isStopped=true
}
}
package com.biganto.visual.roompark.presentation.screen.photo.util
import android.content.Context
import android.graphics.Point
import android.view.View
import android.view.WindowManager
import butterknife.BindView
import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.base.RoomParkApplication
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.github.chrisbanes.photoview.PhotoView
import com.google.android.material.textview.MaterialTextView
import timber.log.Timber
import javax.security.auth.callback.Callback
import kotlin.math.absoluteValue
/**
* Created by Vladislav Bogdashkin on 16.10.2019.
*/
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
}
fun indexById(id:Int):Int = list.indexOfFirst { it.photoId == id }
override val vhKlazz = PhotosViewHolder::class
override fun getVhLayout(): Int = R.layout.photo_page_viewholder
}
class PhotosViewHolder(itemView: View) : CommonViewHolder<PhotoModel>(itemView) {
@BindView(R.id.photo_view)
lateinit var photoPreview: PhotoView
@BindView(R.id.photo_description)
lateinit var description: MaterialTextView
private val picassoAsync by lazy {
return@lazy RoomParkApplication.component.providePicassoAsync()
}
private val windowSize by lazy {
val pSize: Point = Point()
(itemView.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager)
.defaultDisplay.getSize(pSize)
pSize
}
override fun onViewBound(model: PhotoModel) {
description.visibility = if (model.description != null) View.VISIBLE else View.GONE
model.description?.let { description.text = it }
model.resolutionList.lowelest()?.let {
picassoAsync
.load(it.url)
.centerCrop()
.fit()
.into(photoPreview, object :Callback, com.squareup.picasso.Callback {
override fun onSuccess() {
model.resolutionList
.onEach { Timber.d("val ensure: ${it.resWidth} : ${it.resHeight}") }
.minBy {
((windowSize.x - it.resWidth + .1f).absoluteValue
+ (windowSize.y - it.resHeight + .1f).absoluteValue
)
}
?.let {photo ->
Timber.d("val: ${photo.resWidth} : ${photo.resHeight}")
picassoAsync
.load(photo.url)
.centerCrop()
.fit()
.into(photoPreview)
}
}
override fun onError(e: Exception?) {
model.resolutionList
.onEach { Timber.d("val ensure: ${it.resWidth} : ${it.resHeight}") }
.minBy {
((windowSize.x - it.resWidth + .1f).absoluteValue
+ (windowSize.y - it.resHeight + .1f).absoluteValue
)
}
?.let {
Timber.d("val: ${it.resWidth} : ${it.resHeight}")
picassoAsync
.load(it.url)
.centerCrop()
.fit()
.into(photoPreview)
}
}
})
}
}
}
private fun List<PhotoResolutionModel>.lowelest() =
this.minBy { it.resWidth * it.resHeight }
\ No newline at end of file
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
android:id="@+id/linearLayout6" android:id="@+id/linearLayout6"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/colorOpacityBackground"> android:background="#000000">
<com.google.android.material.textview.MaterialTextView <com.google.android.material.textview.MaterialTextView
android:id="@+id/photoTitle" android:id="@+id/photoTitle"
...@@ -53,29 +53,38 @@ ...@@ -53,29 +53,38 @@
android:layout_height="24dp" android:layout_height="24dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline2" app:layout_constraintTop_toTopOf="@+id/guideline2"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/iic_full_view" /> app:srcCompat="@drawable/iic_full_view" />
<ImageView <ImageView
android:id="@+id/change_size_button" android:id="@+id/change_size_button"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline2" app:layout_constraintTop_toTopOf="@+id/guideline2"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@drawable/iic_full_view" /> 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_width="0dp"
android:layout_height="0dp" android:layout_height="48dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:orientation="horizontal" android:orientation="horizontal"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/change_size_button" app:layout_constraintEnd_toStartOf="@+id/change_size_button"
app:layout_constraintStart_toEndOf="@+id/show_full_button" app:layout_constraintStart_toEndOf="@+id/show_full_button"
app:layout_constraintTop_toTopOf="@+id/guideline2" /> app:layout_constraintTop_toTopOf="@+id/guideline2"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -25,4 +25,6 @@ ext { ...@@ -25,4 +25,6 @@ ext {
rxRelayVersion = '2.1.1' rxRelayVersion = '2.1.1'
exoPlayerVersion = "2.10.8" exoPlayerVersion = "2.10.8"
photoViewVersion = "2.0.0" photoViewVersion = "2.0.0"
viewPager2Version = "1.0.0"
glideVersion = "4.11.0"
} }
\ No newline at end of file
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