diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderProgressIndicator.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderProgressIndicator.kt index 0858818636..2d17a4d950 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderProgressIndicator.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderProgressIndicator.kt @@ -8,7 +8,7 @@ import android.view.animation.LinearInterpolator import android.view.animation.RotateAnimation import android.widget.FrameLayout import androidx.annotation.IntRange -import androidx.core.view.isVisible +import androidx.dynamicanimation.animation.DynamicAnimation import com.google.android.material.progressindicator.CircularProgressIndicator /** @@ -44,34 +44,71 @@ class ReaderProgressIndicator @JvmOverloads constructor( layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT) indicator = CircularProgressIndicator(context) indicator.max = 100 + indicator.isIndeterminate = true addView(indicator) } override fun onAttachedToWindow() { super.onAttachedToWindow() - if (indicator.isVisible && animation == null) { - startAnimation(rotateAnimation) - } + updateRotateAnimation() } override fun onDetachedFromWindow() { super.onDetachedFromWindow() - clearAnimation() + updateRotateAnimation() } fun show() { indicator.show() - if (animation == null) { - startAnimation(rotateAnimation) - } + updateRotateAnimation() } fun hide() { indicator.hide() - clearAnimation() + updateRotateAnimation() } + /** + * Sets the current indicator progress to the specified value. + * + * @param progress Indicator will be set indeterminate if this value is 0 + */ fun setProgress(@IntRange(from = 0, to = 100) progress: Int, animated: Boolean = true) { - indicator.setProgressCompat(progress, animated) + if (progress > 0) { + indicator.setProgressCompat(progress, animated) + } else if (!indicator.isIndeterminate) { + indicator.hide() + indicator.isIndeterminate = true + indicator.show() + } + updateRotateAnimation() + } + + fun setCompleteProgressAndHide() { + val listener = object : DynamicAnimation.OnAnimationEndListener { + override fun onAnimationEnd( + animation: DynamicAnimation<*>?, + canceled: Boolean, + value: Float, + velocity: Float + ) { + hide() + indicator.progressDrawable?.removeSpringAnimationEndListener(this) + } + } + + indicator.progressDrawable?.addSpringAnimationEndListener(listener) + indicator.setProgressCompat(100, true) + updateRotateAnimation(forceRotate = true) + } + + private fun updateRotateAnimation(forceRotate: Boolean = false) { + if (forceRotate || (indicator.isShown && !indicator.isIndeterminate)) { + if (animation == null && isAttachedToWindow) { + startAnimation(rotateAnimation) + } + } else { + clearAnimation() + } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt index 814b16d334..2b5d9952aa 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt @@ -245,8 +245,7 @@ class PagerPageHolder( * Called when the page is ready. */ private fun setImage() { - progressIndicator.setProgress(100) - progressIndicator.hide() + progressIndicator.setCompleteProgressAndHide() retryButton?.isVisible = false decodeErrorLayout?.isVisible = false @@ -332,13 +331,6 @@ class PagerPageHolder( initRetryButton().isVisible = true } - /** - * Called when the image is decoded and going to be displayed. - */ - private fun onImageDecoded() { - progressIndicator.hide() - } - /** * Called when an image fails to decode. */ @@ -373,7 +365,6 @@ class PagerPageHolder( ZoomType.Right -> setScaleAndCenter(scale, PointF(sWidth.toFloat(), 0f)) ZoomType.Center -> setScaleAndCenter(scale, center.also { it?.y = 0f }) } - onImageDecoded() } override fun onImageLoadError(e: Exception) { @@ -504,7 +495,6 @@ class PagerPageHolder( result.start() } setImageDrawable(result) - onImageDecoded() }, onError = { onImageDecodeError() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt index d5470ed97f..1aac652d2f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt @@ -265,9 +265,7 @@ class WebtoonPageHolder( * Called when the page is ready. */ private fun setImage() { - progressContainer.isVisible = true - progressIndicator.setProgress(100) - progressIndicator.hide() + progressIndicator.setCompleteProgressAndHide() retryContainer?.isVisible = false removeDecodeErrorLayout() @@ -325,13 +323,6 @@ class WebtoonPageHolder( initRetryLayout().isVisible = true } - /** - * Called when the image is decoded and going to be displayed. - */ - private fun onImageDecoded() { - progressContainer.isVisible = false - } - /** * Called when the image fails to decode. */ @@ -382,10 +373,6 @@ class WebtoonPageHolder( setCropBorders(cropBorders) setOnImageEventListener( object : SubsamplingScaleImageView.DefaultOnImageEventListener() { - override fun onReady() { - onImageDecoded() - } - override fun onImageLoadError(e: Exception) { onImageDecodeError() } @@ -517,7 +504,6 @@ class WebtoonPageHolder( result.start() } setImageDrawable(result) - onImageDecoded() }, onError = { onImageDecodeError()