diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/list/lifecycle/PagerLifecycleDispatcher.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/list/lifecycle/PagerLifecycleDispatcher.kt index b767396e1..6f43da7de 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/list/lifecycle/PagerLifecycleDispatcher.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/list/lifecycle/PagerLifecycleDispatcher.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.core.ui.list.lifecycle +import android.view.View import androidx.core.view.children import androidx.viewpager2.widget.ViewPager2 import org.koitharu.kotatsu.core.util.ext.recyclerView @@ -8,16 +9,59 @@ class PagerLifecycleDispatcher( private val pager: ViewPager2, ) : ViewPager2.OnPageChangeCallback() { + private var pendingUpdate: OneShotLayoutListener? = null + override fun onPageSelected(position: Int) { - super.onPageSelected(position) - val rv = pager.recyclerView ?: return - for (child in rv.children) { - val wh = rv.getChildViewHolder(child) ?: continue - (wh as? LifecycleAwareViewHolder)?.setIsCurrent(wh.absoluteAdapterPosition == position) - } + setResumedPage(position) } fun invalidate() { - onPageSelected(pager.currentItem) + setResumedPage(pager.currentItem) + } + + private fun setResumedPage(position: Int) { + pendingUpdate?.cancel() + pendingUpdate = null + var hasResumedItem = false + val rv = pager.recyclerView ?: return + if (rv.childCount == 0) { + return + } + for (child in rv.children) { + val wh = rv.getChildViewHolder(child) ?: continue + val isCurrent = wh.absoluteAdapterPosition == position + (wh as? LifecycleAwareViewHolder)?.setIsCurrent(isCurrent) + if (isCurrent) { + hasResumedItem = true + } + } + if (!hasResumedItem) { + rv.addOnLayoutChangeListener(OneShotLayoutListener(rv, position).also { pendingUpdate = it }) + } + } + + private inner class OneShotLayoutListener( + private val view: View, + private val targetPosition: Int, + ) : View.OnLayoutChangeListener { + + override fun onLayoutChange( + v: View?, + left: Int, + top: Int, + right: Int, + bottom: Int, + oldLeft: Int, + oldTop: Int, + oldRight: Int, + oldBottom: Int + ) { + view.removeOnLayoutChangeListener(this) + setResumedPage(targetPosition) + } + + fun cancel() { + view.removeOnLayoutChangeListener(this) + } } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BasePageHolder.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BasePageHolder.kt index a85d98616..bfc3205e6 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BasePageHolder.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/pager/BasePageHolder.kt @@ -5,6 +5,7 @@ import androidx.annotation.CallSuper import androidx.lifecycle.LifecycleOwner import androidx.viewbinding.ViewBinding import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView +import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.os.NetworkState import org.koitharu.kotatsu.core.ui.list.lifecycle.LifecycleAwareViewHolder @@ -81,6 +82,7 @@ abstract class BasePageHolder( protected fun SubsamplingScaleImageView.applyDownSampling(isForeground: Boolean) { downSampling = when { isForeground || !settings.isReaderOptimizationEnabled -> 1 + BuildConfig.DEBUG -> 32 context.isLowRamDevice() -> 8 else -> 4 }