Fix webtoon scrolling

This commit is contained in:
Koitharu
2020-03-10 18:19:46 +02:00
parent cbba4a850c
commit e47d494b1c
9 changed files with 27 additions and 54 deletions

View File

@@ -11,10 +11,11 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koitharu.kotatsu.core.model.Manga
import org.koitharu.kotatsu.core.model.MangaPage
import org.koitharu.kotatsu.core.model.MangaState
import org.koitharu.kotatsu.domain.MangaProviderFactory
import org.koitharu.kotatsu.ui.common.BaseFragment
import org.koitharu.kotatsu.ui.reader.*
import org.koitharu.kotatsu.ui.reader.PageLoader
import org.koitharu.kotatsu.ui.reader.ReaderListener
import org.koitharu.kotatsu.ui.reader.ReaderState
abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayoutId),
OnBoundsScrollListener {
@@ -23,7 +24,7 @@ abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayout
protected lateinit var loader: PageLoader
private set
private lateinit var pages: GroupedList<Long, MangaPage>
protected var adapter: BaseReaderAdapter<*>? = null
protected var adapter: BaseReaderAdapter? = null
private set
val hasItems: Boolean
@@ -218,7 +219,7 @@ abstract class AbstractReader(contentLayoutId: Int) : BaseFragment(contentLayout
protected abstract fun setCurrentItem(position: Int, isSmooth: Boolean)
protected abstract fun onCreateAdapter(dataSet: GroupedList<Long, MangaPage>): BaseReaderAdapter<*>
protected abstract fun onCreateAdapter(dataSet: GroupedList<Long, MangaPage>): BaseReaderAdapter
protected companion object {

View File

@@ -5,17 +5,17 @@ import androidx.recyclerview.widget.RecyclerView
import org.koitharu.kotatsu.core.model.MangaPage
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
abstract class BaseReaderAdapter<E>(private val pages: GroupedList<Long, MangaPage>) :
RecyclerView.Adapter<BaseViewHolder<MangaPage, E>>() {
abstract class BaseReaderAdapter(private val pages: GroupedList<Long, MangaPage>) :
RecyclerView.Adapter<BaseViewHolder<MangaPage, Unit>>() {
init {
@Suppress("LeakingThis")
setHasStableIds(true)
}
override fun onBindViewHolder(holder: BaseViewHolder<MangaPage, E>, position: Int) {
override fun onBindViewHolder(holder: BaseViewHolder<MangaPage, Unit>, position: Int) {
val item = pages[position]
holder.bind(item, getExtra(item, position))
holder.bind(item, Unit)
}
fun getItem(position: Int) = pages[position]
@@ -40,13 +40,11 @@ abstract class BaseReaderAdapter<E>(private val pages: GroupedList<Long, MangaPa
final override fun getItemCount() = pages.size
final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<MangaPage, E> {
final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<MangaPage, Unit> {
return onCreateViewHolder(parent).also(this::onViewHolderCreated)
}
protected abstract fun getExtra(item: MangaPage, position: Int): E
protected open fun onViewHolderCreated(holder: BaseViewHolder<MangaPage, Unit>) = Unit
protected open fun onViewHolderCreated(holder: BaseViewHolder<MangaPage, E>) = Unit
protected abstract fun onCreateViewHolder(parent: ViewGroup): BaseViewHolder<MangaPage, E>
protected abstract fun onCreateViewHolder(parent: ViewGroup): BaseViewHolder<MangaPage, Unit>
}

View File

@@ -30,7 +30,7 @@ class PagerReaderFragment() : AbstractReader(R.layout.fragment_reader_standard)
super.onDestroyView()
}
override fun onCreateAdapter(dataSet: GroupedList<Long, MangaPage>): BaseReaderAdapter<*> {
override fun onCreateAdapter(dataSet: GroupedList<Long, MangaPage>): BaseReaderAdapter {
return PagesAdapter(dataSet, loader)
}

View File

@@ -9,9 +9,7 @@ import org.koitharu.kotatsu.ui.reader.PageLoader
class PagesAdapter(
pages: GroupedList<Long, MangaPage>,
private val loader: PageLoader
) : BaseReaderAdapter<Unit>(pages) {
) : BaseReaderAdapter(pages) {
override fun onCreateViewHolder(parent: ViewGroup) = PageHolder(parent, loader)
override fun getExtra(item: MangaPage, position: Int) = Unit
}

View File

@@ -1,20 +1,15 @@
package org.koitharu.kotatsu.ui.reader.wetoon
import android.view.Gravity
import android.view.ViewGroup
import org.koitharu.kotatsu.core.model.MangaPage
import org.koitharu.kotatsu.ui.reader.PageLoader
import org.koitharu.kotatsu.ui.reader.base.BaseReaderAdapter
import org.koitharu.kotatsu.ui.reader.base.GroupedList
import org.koitharu.kotatsu.ui.reader.PageLoader
class WebtoonAdapter(
pages: GroupedList<Long, MangaPage>,
private val loader: PageLoader
) : BaseReaderAdapter<Int>(pages) {
var pageGravity: Int = Gravity.TOP
) : BaseReaderAdapter(pages) {
override fun onCreateViewHolder(parent: ViewGroup) = WebtoonHolder(parent, loader)
override fun getExtra(item: MangaPage, position: Int) = pageGravity
}

View File

@@ -19,9 +19,6 @@ class WebtoonFrameLayout @JvmOverloads constructor(
}
fun dispatchVerticalScroll(dy: Int): Int {
if (!target.isImageLoaded) {
return dy //consume all scrolling
}
target.getPanRemaining(pan)
val c = target.center ?: return 0
val s = target.scale

View File

@@ -1,7 +1,6 @@
package org.koitharu.kotatsu.ui.reader.wetoon
import android.graphics.PointF
import android.view.Gravity
import android.view.ViewGroup
import androidx.core.net.toUri
import androidx.core.view.isVisible
@@ -17,11 +16,10 @@ import org.koitharu.kotatsu.utils.ext.getDisplayMessage
class WebtoonHolder(parent: ViewGroup, private val loader: PageLoader) :
BaseViewHolder<MangaPage, Int>(parent, R.layout.item_page_webtoon),
BaseViewHolder<MangaPage, Unit>(parent, R.layout.item_page_webtoon),
SubsamplingScaleImageView.OnImageEventListener, CoroutineScope by loader {
private var job: Job? = null
private var yFactor = 0f
init {
ssiv.setOnImageEventListener(this)
@@ -30,12 +28,7 @@ class WebtoonHolder(parent: ViewGroup, private val loader: PageLoader) :
}
}
override fun onBind(data: MangaPage, extra: Int) {
yFactor = when(extra) {
Gravity.TOP -> 0f
Gravity.BOTTOM -> 1f
else -> 0.5f
}
override fun onBind(data: MangaPage, extra: Unit) {
doLoad(data, force = false)
}
@@ -63,7 +56,14 @@ class WebtoonHolder(parent: ViewGroup, private val loader: PageLoader) :
ssiv.minScale = ssiv.width / ssiv.sWidth.toFloat()
ssiv.setScaleAndCenter(
ssiv.minScale,
PointF(ssiv.sWidth / 2f, ssiv.sHeight * yFactor)
PointF(
ssiv.sWidth / 2f,
if (itemView.top < 0) {
ssiv.sHeight.toFloat()
} else {
0f
}
)
)
}

View File

@@ -31,7 +31,7 @@ class WebtoonReaderFragment : AbstractReader(R.layout.fragment_reader_webtoon) {
recyclerView.doOnCurrentItemChanged(::notifyPageChanged)
}
override fun onCreateAdapter(dataSet: GroupedList<Long, MangaPage>): BaseReaderAdapter<*> {
override fun onCreateAdapter(dataSet: GroupedList<Long, MangaPage>): BaseReaderAdapter {
return WebtoonAdapter(dataSet, loader)
}

View File

@@ -12,8 +12,6 @@ class WebtoonRecyclerView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : RecyclerView(context, attrs, defStyleAttr) {
private var lastScrollDirection = 0
override fun dispatchNestedPreScroll(
dx: Int,
dy: Int,
@@ -49,18 +47,4 @@ class WebtoonRecyclerView @JvmOverloads constructor(
scrollY -= (child as WebtoonFrameLayout).dispatchVerticalScroll(scrollY)
return dy - scrollY
}
override fun onScrolled(dx: Int, dy: Int) {
val direction = dy.sign
if (direction != lastScrollDirection) {
(adapter as? WebtoonAdapter)?.let {
it.pageGravity = if (dy < 0) {
Gravity.BOTTOM
} else {
Gravity.TOP
}
lastScrollDirection = direction
}
}
}
}