Respect system animation disabling #341

This commit is contained in:
Koitharu
2023-04-07 18:33:47 +03:00
parent dba506cb42
commit 16c3e61984
8 changed files with 54 additions and 44 deletions

View File

@@ -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"

View File

@@ -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<Segment>
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<Segment>) {
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(

View File

@@ -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<ListHeader2, ListModel, ItemHeader2Binding>(
{ 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)
}
}
}

View File

@@ -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() {

View File

@@ -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<FragmentReaderStandardBinding>() {
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<ReaderPage>, pendingState: ReaderState?) {

View File

@@ -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<FragmentReaderStandardBinding>() {
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 {

View File

@@ -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<FragmentReaderWebtoonBinding>() {
}
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) {

View File

@@ -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()
}