Smooth auto scrolling #319
parent
b45147563a
commit
bc4dd1c507
@ -0,0 +1,72 @@
|
||||
package org.koitharu.kotatsu.reader.ui
|
||||
|
||||
import androidx.annotation.FloatRange
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.coroutineScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.roundToLong
|
||||
|
||||
private const val MIN_SPEED = 0.1
|
||||
private const val MAX_DELAY = 80L
|
||||
private const val MAX_SWITCH_DELAY = 20_000L
|
||||
|
||||
class ScrollTimer(
|
||||
private val lifecycleOwner: LifecycleOwner,
|
||||
private val listener: ReaderControlDelegate.OnInteractionListener,
|
||||
) {
|
||||
|
||||
private var job: Job? = null
|
||||
private var delayMs: Long = 10L
|
||||
private var pageSwitchDelay: Long = 100L
|
||||
|
||||
@FloatRange(from = 0.0, to = 1.0)
|
||||
var speed: Float = 0f
|
||||
set(value) {
|
||||
if (field != value) {
|
||||
field = value
|
||||
onSpeedChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSpeedChanged() {
|
||||
if (speed < MIN_SPEED) {
|
||||
delayMs = 0L
|
||||
pageSwitchDelay = 0L
|
||||
} else {
|
||||
val speedFactor = 1 - speed + MIN_SPEED
|
||||
delayMs = (MAX_DELAY * speedFactor).roundToLong()
|
||||
pageSwitchDelay = (MAX_SWITCH_DELAY * speedFactor).roundToLong()
|
||||
}
|
||||
if ((job == null) != (delayMs == 0L)) {
|
||||
restartJob()
|
||||
}
|
||||
}
|
||||
|
||||
private fun restartJob() {
|
||||
job?.cancel()
|
||||
if (delayMs == 0L) {
|
||||
job = null
|
||||
return
|
||||
}
|
||||
job = lifecycleOwner.lifecycle.coroutineScope.launch {
|
||||
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
var accumulator = 0L
|
||||
while (isActive) {
|
||||
delay(delayMs)
|
||||
if (!listener.scrollBy(1)) {
|
||||
accumulator += delayMs
|
||||
}
|
||||
if (accumulator >= pageSwitchDelay) {
|
||||
listener.switchPageBy(1)
|
||||
accumulator -= pageSwitchDelay
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue