Fix webtoon under scale
This commit is contained in:
@@ -12,7 +12,7 @@ class WebtoonFrameLayout @JvmOverloads constructor(
|
|||||||
@AttrRes defStyleAttr: Int = 0,
|
@AttrRes defStyleAttr: Int = 0,
|
||||||
) : FrameLayout(context, attrs, defStyleAttr) {
|
) : FrameLayout(context, attrs, defStyleAttr) {
|
||||||
|
|
||||||
private val target by lazy(LazyThreadSafetyMode.NONE) {
|
val target by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
findViewById<WebtoonImageView>(R.id.ssiv)
|
findViewById<WebtoonImageView>(R.id.ssiv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,18 @@ class WebtoonImageView @JvmOverloads constructor(
|
|||||||
setMeasuredDimension(width, height)
|
setMeasuredDimension(width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||||
|
super.onSizeChanged(w, h, oldw, oldh)
|
||||||
|
if (oldh == h || oldw == 0 || oldh == 0 || scrollRange == SCROLL_UNKNOWN) return
|
||||||
|
|
||||||
|
computeScrollRange()
|
||||||
|
val container = parents.firstNotNullOfOrNull { it as? WebtoonFrameLayout } ?: return
|
||||||
|
val parentHeight = parentHeight()
|
||||||
|
if (scrollPos != 0 && container.bottom < parentHeight) {
|
||||||
|
scrollTo(scrollRange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun scrollToInternal(pos: Int) {
|
private fun scrollToInternal(pos: Int) {
|
||||||
scrollPos = pos
|
scrollPos = pos
|
||||||
ct.set(sWidth / 2f, (height / 2f + pos.toFloat()) / minScale)
|
ct.set(sWidth / 2f, (height / 2f + pos.toFloat()) / minScale)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.reader.ui.pager.webtoon
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import androidx.core.view.ViewCompat.TYPE_TOUCH
|
import androidx.core.view.ViewCompat.TYPE_TOUCH
|
||||||
|
import androidx.core.view.forEach
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import org.koitharu.kotatsu.core.util.ext.findCenterViewPosition
|
import org.koitharu.kotatsu.core.util.ext.findCenterViewPosition
|
||||||
import java.util.LinkedList
|
import java.util.LinkedList
|
||||||
@@ -13,6 +14,13 @@ class WebtoonRecyclerView @JvmOverloads constructor(
|
|||||||
|
|
||||||
private var onPageScrollListeners: MutableList<OnPageScrollListener>? = null
|
private var onPageScrollListeners: MutableList<OnPageScrollListener>? = null
|
||||||
|
|
||||||
|
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
|
||||||
|
super.onMeasure(widthSpec, heightSpec)
|
||||||
|
forEach { child ->
|
||||||
|
(child as WebtoonFrameLayout).target.requestLayout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun startNestedScroll(axes: Int) = startNestedScroll(axes, TYPE_TOUCH)
|
override fun startNestedScroll(axes: Int) = startNestedScroll(axes, TYPE_TOUCH)
|
||||||
|
|
||||||
override fun startNestedScroll(axes: Int, type: Int): Boolean = true
|
override fun startNestedScroll(axes: Int, type: Int): Boolean = true
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.koitharu.kotatsu.reader.ui.pager.webtoon
|
package org.koitharu.kotatsu.reader.ui.pager.webtoon
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
import android.animation.ValueAnimator
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Matrix
|
import android.graphics.Matrix
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
@@ -15,7 +15,7 @@ import android.widget.OverScroller
|
|||||||
import androidx.core.view.GestureDetectorCompat
|
import androidx.core.view.GestureDetectorCompat
|
||||||
|
|
||||||
private const val MAX_SCALE = 2.5f
|
private const val MAX_SCALE = 2.5f
|
||||||
private const val MIN_SCALE = 1f // under-scaling disabled due to buggy nested scroll
|
private const val MIN_SCALE = 0.5f
|
||||||
|
|
||||||
class WebtoonScalingFrame @JvmOverloads constructor(
|
class WebtoonScalingFrame @JvmOverloads constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
@@ -40,7 +40,6 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
|||||||
private var halfHeight = 0f
|
private var halfHeight = 0f
|
||||||
private val translateBounds = RectF()
|
private val translateBounds = RectF()
|
||||||
private val targetHitRect = Rect()
|
private val targetHitRect = Rect()
|
||||||
private var pendingScroll = 0
|
|
||||||
|
|
||||||
var isZoomEnable = true
|
var isZoomEnable = true
|
||||||
set(value) {
|
set(value) {
|
||||||
@@ -101,8 +100,6 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
|||||||
|
|
||||||
if (scale < 1) {
|
if (scale < 1) {
|
||||||
targetChild.getHitRect(targetHitRect)
|
targetChild.getHitRect(targetHitRect)
|
||||||
targetChild.scrollBy(0, pendingScroll)
|
|
||||||
pendingScroll = 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +121,6 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
|||||||
else -> 0f
|
else -> 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
pendingScroll = dy.toInt()
|
|
||||||
transformMatrix.postTranslate(dx, dy)
|
transformMatrix.postTranslate(dx, dy)
|
||||||
syncMatrixValues()
|
syncMatrixValues()
|
||||||
}
|
}
|
||||||
@@ -159,9 +155,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
|||||||
|
|
||||||
override fun onScaleBegin(detector: ScaleGestureDetector): Boolean = true
|
override fun onScaleBegin(detector: ScaleGestureDetector): Boolean = true
|
||||||
|
|
||||||
override fun onScaleEnd(p0: ScaleGestureDetector) {
|
override fun onScaleEnd(p0: ScaleGestureDetector) = Unit
|
||||||
pendingScroll = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private inner class GestureListener : GestureDetector.SimpleOnGestureListener(), Runnable {
|
private inner class GestureListener : GestureDetector.SimpleOnGestureListener(), Runnable {
|
||||||
@@ -175,7 +169,7 @@ class WebtoonScalingFrame @JvmOverloads constructor(
|
|||||||
|
|
||||||
override fun onDoubleTap(e: MotionEvent): Boolean {
|
override fun onDoubleTap(e: MotionEvent): Boolean {
|
||||||
val newScale = if (scale != 1f) 1f else MAX_SCALE * 0.8f
|
val newScale = if (scale != 1f) 1f else MAX_SCALE * 0.8f
|
||||||
ObjectAnimator.ofFloat(scale, newScale).run {
|
ValueAnimator.ofFloat(scale, newScale).run {
|
||||||
interpolator = AccelerateDecelerateInterpolator()
|
interpolator = AccelerateDecelerateInterpolator()
|
||||||
duration = 300
|
duration = 300
|
||||||
addUpdateListener {
|
addUpdateListener {
|
||||||
|
|||||||
Reference in New Issue
Block a user