From 16c3e619841bcd6e740a6eb612a5298e80a07a5b Mon Sep 17 00:00:00 2001 From: Koitharu Date: Fri, 7 Apr 2023 18:33:47 +0300 Subject: [PATCH] Respect system animation disabling #341 --- app/build.gradle | 4 +-- .../base/ui/widgets/SegmentedBarView.kt | 33 ++++++------------- .../kotatsu/list/ui/adapter/ListHeader2AD.kt | 11 +++++-- .../kotatsu/main/ui/MainNavigationDelegate.kt | 8 ++++- .../pager/reversed/ReversedReaderFragment.kt | 13 +++++--- .../ui/pager/standard/PagerReaderFragment.kt | 13 +++++--- .../ui/pager/webtoon/WebtoonReaderFragment.kt | 13 +++++--- .../koitharu/kotatsu/utils/ext/AndroidExt.kt | 3 ++ 8 files changed, 54 insertions(+), 44 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c1b199867..38fc8e0ab 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,8 +15,8 @@ android { applicationId 'org.koitharu.kotatsu' minSdkVersion 21 targetSdkVersion 33 - versionCode 532 - versionName '5.0-a3' + versionCode 533 + versionName '5.0-a4' generatedDensities = [] testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/SegmentedBarView.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/SegmentedBarView.kt index d152c3f10..1125b7839 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/SegmentedBarView.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/SegmentedBarView.kt @@ -12,12 +12,11 @@ import android.view.ViewOutlineProvider import android.view.animation.DecelerateInterpolator import androidx.annotation.ColorInt import androidx.annotation.FloatRange -import androidx.core.graphics.ColorUtils import org.koitharu.kotatsu.parsers.util.replaceWith import org.koitharu.kotatsu.utils.ext.getAnimationDuration import org.koitharu.kotatsu.utils.ext.getThemeColor +import org.koitharu.kotatsu.utils.ext.isAnimationsEnabled import org.koitharu.kotatsu.utils.ext.resolveDp -import kotlin.random.Random import com.google.android.material.R as materialR class SegmentedBarView @JvmOverloads constructor( @@ -34,29 +33,10 @@ class SegmentedBarView @JvmOverloads constructor( private var scaleFactor = 1f private var scaleAnimator: ValueAnimator? = null - var segments: List - get() = segmentsData - set(value) { - scaleAnimator?.cancel() - scaleAnimator = null - segmentsData.replaceWith(value) - updateSizes() - invalidate() - } - init { paint.strokeWidth = context.resources.resolveDp(1f) outlineProvider = OutlineProvider() clipToOutline = true - - if (isInEditMode) { - segments = List(Random.nextInt(3, 5)) { - Segment( - percent = Random.nextFloat(), - color = ColorUtils.HSLToColor(floatArrayOf(Random.nextInt(0, 360).toFloat(), 0.5f, 0.5f)), - ) - } - } } override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { @@ -107,8 +87,15 @@ class SegmentedBarView @JvmOverloads constructor( fun animateSegments(value: List) { scaleAnimator?.cancel() - scaleFactor = 0f segmentsData.replaceWith(value) + if (!context.isAnimationsEnabled) { + scaleAnimator = null + scaleFactor = 1f + updateSizes() + invalidate() + return + } + scaleFactor = 0f updateSizes() invalidate() val animator = ValueAnimator.ofFloat(0f, 1f) @@ -124,7 +111,7 @@ class SegmentedBarView @JvmOverloads constructor( segmentsSizes.clear() segmentsSizes.ensureCapacity(segmentsData.size + 1) var w = width.toFloat() - val maxScale = (scaleFactor * (segments.size - 1)).coerceAtLeast(1f) + val maxScale = (scaleFactor * (segmentsData.size - 1)).coerceAtLeast(1f) for ((index, segment) in segmentsData.withIndex()) { val scale = (scaleFactor * (index + 1) / maxScale).coerceAtMost(1f) val segmentWidth = (w * segment.percent).coerceAtLeast( diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/ListHeader2AD.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/ListHeader2AD.kt index ba37506f5..d8ab7ce94 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/ListHeader2AD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/adapter/ListHeader2AD.kt @@ -6,12 +6,13 @@ import org.koitharu.kotatsu.databinding.ItemHeader2Binding import org.koitharu.kotatsu.list.ui.model.ListHeader2 import org.koitharu.kotatsu.list.ui.model.ListModel import org.koitharu.kotatsu.parsers.model.MangaTag +import org.koitharu.kotatsu.utils.ext.isAnimationsEnabled import org.koitharu.kotatsu.utils.ext.setTextAndVisible fun listHeader2AD( listener: MangaListListener, ) = adapterDelegateViewBinding( - { layoutInflater, parent -> ItemHeader2Binding.inflate(layoutInflater, parent, false) } + { layoutInflater, parent -> ItemHeader2Binding.inflate(layoutInflater, parent, false) }, ) { var ignoreChecking = false @@ -26,11 +27,15 @@ fun listHeader2AD( bind { payloads -> if (payloads.isNotEmpty()) { - binding.scrollView.smoothScrollTo(0, 0) + if (context.isAnimationsEnabled) { + binding.scrollView.smoothScrollTo(0, 0) + } else { + binding.scrollView.scrollTo(0, 0) + } } ignoreChecking = true binding.chipsTags.setChips(item.chips) // TODO use recyclerview ignoreChecking = false binding.textViewFilter.setTextAndVisible(item.sortOrder?.titleRes ?: 0) } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainNavigationDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainNavigationDelegate.kt index 5573fbfd4..92d71241d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainNavigationDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainNavigationDelegate.kt @@ -15,6 +15,8 @@ import org.koitharu.kotatsu.explore.ui.ExploreFragment import org.koitharu.kotatsu.settings.tools.ToolsFragment import org.koitharu.kotatsu.shelf.ui.ShelfFragment import org.koitharu.kotatsu.tracker.ui.feed.FeedFragment +import org.koitharu.kotatsu.utils.ext.firstVisibleItemPosition +import org.koitharu.kotatsu.utils.ext.isAnimationsEnabled import java.util.LinkedList private const val TAG_PRIMARY = "primary" @@ -44,7 +46,11 @@ class MainNavigationDelegate( return } val recyclerView = fragment.recyclerView - recyclerView.smoothScrollToPosition(0) + if (recyclerView.context.isAnimationsEnabled) { + recyclerView.smoothScrollToPosition(0) + } else { + recyclerView.firstVisibleItemPosition = 0 + } } override fun handleOnBackPressed() { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt index 19736f5c6..1447a4b36 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/reversed/ReversedReaderFragment.kt @@ -18,6 +18,7 @@ import org.koitharu.kotatsu.reader.ui.pager.BaseReaderAdapter import org.koitharu.kotatsu.reader.ui.pager.ReaderPage import org.koitharu.kotatsu.reader.ui.pager.standard.PagerReaderFragment import org.koitharu.kotatsu.utils.ext.doOnPageChanged +import org.koitharu.kotatsu.utils.ext.isAnimationsEnabled import org.koitharu.kotatsu.utils.ext.recyclerView import org.koitharu.kotatsu.utils.ext.resetTransformations import org.koitharu.kotatsu.utils.ext.viewLifecycleScope @@ -74,15 +75,17 @@ class ReversedReaderFragment : BaseReader() { override fun switchPageBy(delta: Int) { with(binding.pager) { - setCurrentItem(currentItem - delta, true) + setCurrentItem(currentItem - delta, context.isAnimationsEnabled) } } override fun switchPageTo(position: Int, smooth: Boolean) { - binding.pager.setCurrentItem( - reversed(position), - smooth && (binding.pager.currentItem - position).absoluteValue < PagerReaderFragment.SMOOTH_SCROLL_LIMIT, - ) + with(binding.pager) { + setCurrentItem( + reversed(position), + smooth && context.isAnimationsEnabled && (currentItem - position).absoluteValue < PagerReaderFragment.SMOOTH_SCROLL_LIMIT, + ) + } } override fun onPagesChanged(pages: List, pendingState: ReaderState?) { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt index 4ec6d759f..49b4e1239 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/standard/PagerReaderFragment.kt @@ -17,6 +17,7 @@ import org.koitharu.kotatsu.reader.ui.pager.BaseReader import org.koitharu.kotatsu.reader.ui.pager.BaseReaderAdapter import org.koitharu.kotatsu.reader.ui.pager.ReaderPage import org.koitharu.kotatsu.utils.ext.doOnPageChanged +import org.koitharu.kotatsu.utils.ext.isAnimationsEnabled import org.koitharu.kotatsu.utils.ext.recyclerView import org.koitharu.kotatsu.utils.ext.resetTransformations import org.koitharu.kotatsu.utils.ext.viewLifecycleScope @@ -93,15 +94,17 @@ class PagerReaderFragment : BaseReader() { override fun switchPageBy(delta: Int) { with(binding.pager) { - setCurrentItem(currentItem + delta, true) + setCurrentItem(currentItem + delta, context.isAnimationsEnabled) } } override fun switchPageTo(position: Int, smooth: Boolean) { - binding.pager.setCurrentItem( - position, - smooth && (binding.pager.currentItem - position).absoluteValue < SMOOTH_SCROLL_LIMIT, - ) + with(binding.pager) { + setCurrentItem( + position, + smooth && context.isAnimationsEnabled && (currentItem - position).absoluteValue < SMOOTH_SCROLL_LIMIT, + ) + } } override fun getCurrentState(): ReaderState? = bindingOrNull()?.run { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt index cf61f2c9f..226961f32 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/pager/webtoon/WebtoonReaderFragment.kt @@ -17,6 +17,7 @@ import org.koitharu.kotatsu.reader.ui.pager.BaseReaderAdapter import org.koitharu.kotatsu.reader.ui.pager.ReaderPage import org.koitharu.kotatsu.utils.ext.findCenterViewPosition import org.koitharu.kotatsu.utils.ext.firstVisibleItemPosition +import org.koitharu.kotatsu.utils.ext.isAnimationsEnabled import org.koitharu.kotatsu.utils.ext.viewLifecycleScope import javax.inject.Inject @@ -103,11 +104,13 @@ class WebtoonReaderFragment : BaseReader() { } override fun switchPageBy(delta: Int) { - binding.recyclerView.smoothScrollBy( - 0, - (binding.recyclerView.height * 0.9).toInt() * delta, - scrollInterpolator, - ) + with(binding.recyclerView) { + if (context.isAnimationsEnabled) { + smoothScrollBy(0, (height * 0.9).toInt() * delta, scrollInterpolator) + } else { + nestedScrollBy(0, (height * 0.9).toInt() * delta) + } + } } override fun switchPageTo(position: Int, smooth: Boolean) { diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt index b595f5b60..654297d84 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/AndroidExt.kt @@ -135,6 +135,9 @@ fun Window.setNavigationBarTransparentCompat(context: Context, elevation: Float, val Context.animatorDurationScale: Float get() = Settings.Global.getFloat(this.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1f) +val Context.isAnimationsEnabled: Boolean + get() = animatorDurationScale > 0f + fun ViewPropertyAnimator.applySystemAnimatorScale(context: Context): ViewPropertyAnimator = apply { this.duration = (this.duration * context.animatorDurationScale).toLong() }