mirror of
https://github.com/gedoor/legado.git
synced 2024-07-06 23:47:49 +08:00
优化
This commit is contained in:
parent
5315f6bcef
commit
d96de11b12
@ -6,7 +6,6 @@ import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import android.view.Gravity
|
||||
import android.view.InputDevice
|
||||
import android.view.KeyEvent
|
||||
@ -93,11 +92,11 @@ import io.legado.app.ui.widget.PopupAction
|
||||
import io.legado.app.ui.widget.dialog.PhotoDialog
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
import io.legado.app.utils.ACache
|
||||
import io.legado.app.utils.Debounce
|
||||
import io.legado.app.utils.LogUtils
|
||||
import io.legado.app.utils.StartActivityContract
|
||||
import io.legado.app.utils.SyncedRenderer
|
||||
import io.legado.app.utils.applyOpenTint
|
||||
import io.legado.app.utils.buildMainHandler
|
||||
import io.legado.app.utils.getPrefBoolean
|
||||
import io.legado.app.utils.getPrefString
|
||||
import io.legado.app.utils.hexString
|
||||
@ -118,7 +117,6 @@ import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.visible
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.Runnable
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
@ -217,15 +215,13 @@ class ReadBookActivity : BaseReadBookActivity(),
|
||||
override val pageFactory: TextPageFactory get() = binding.readView.pageFactory
|
||||
override val headerHeight: Int get() = binding.readView.curPage.headerHeight
|
||||
private val menuLayoutIsVisible get() = bottomDialog > 0 || binding.readMenu.isVisible
|
||||
private val nextPageRunnable by lazy { Runnable { keyPage(PageDirection.NEXT) } }
|
||||
private val prevPageRunnable by lazy { Runnable { keyPage(PageDirection.PREV) } }
|
||||
private val nextPageDebounce by lazy { Debounce { keyPage(PageDirection.NEXT) } }
|
||||
private val prevPageDebounce by lazy { Debounce { keyPage(PageDirection.PREV) } }
|
||||
private var bookChanged = false
|
||||
private var pageChanged = false
|
||||
private var reloadContent = false
|
||||
private val autoPageRenderer by lazy { SyncedRenderer { doAutoPage(it) } }
|
||||
private var autoPageScrollOffset = 0.0
|
||||
private val handler by lazy { buildMainHandler() }
|
||||
private var lastKeyPageTime = 0L
|
||||
|
||||
//恢复跳转前进度对话框的交互结果
|
||||
private var confirmRestoreProcess: Boolean? = null
|
||||
@ -624,38 +620,39 @@ class ReadBookActivity : BaseReadBookActivity(),
|
||||
if (menuLayoutIsVisible) {
|
||||
return super.onKeyDown(keyCode, event)
|
||||
}
|
||||
val longPress = event.repeatCount > 0
|
||||
when {
|
||||
isPrevKey(keyCode) -> {
|
||||
handleKeyPage(PageDirection.PREV)
|
||||
handleKeyPage(PageDirection.PREV, longPress)
|
||||
return true
|
||||
}
|
||||
|
||||
isNextKey(keyCode) -> {
|
||||
handleKeyPage(PageDirection.NEXT)
|
||||
handleKeyPage(PageDirection.NEXT, longPress)
|
||||
return true
|
||||
}
|
||||
}
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_VOLUME_UP -> if (volumeKeyPage(PageDirection.PREV)) {
|
||||
KeyEvent.KEYCODE_VOLUME_UP -> if (volumeKeyPage(PageDirection.PREV, longPress)) {
|
||||
return true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_VOLUME_DOWN -> if (volumeKeyPage(PageDirection.NEXT)) {
|
||||
KeyEvent.KEYCODE_VOLUME_DOWN -> if (volumeKeyPage(PageDirection.NEXT, longPress)) {
|
||||
return true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_PAGE_UP -> {
|
||||
handleKeyPage(PageDirection.PREV)
|
||||
handleKeyPage(PageDirection.PREV, longPress)
|
||||
return true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_PAGE_DOWN -> {
|
||||
handleKeyPage(PageDirection.NEXT)
|
||||
handleKeyPage(PageDirection.NEXT, longPress)
|
||||
return true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_SPACE -> {
|
||||
handleKeyPage(PageDirection.NEXT)
|
||||
handleKeyPage(PageDirection.NEXT, longPress)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -669,7 +666,7 @@ class ReadBookActivity : BaseReadBookActivity(),
|
||||
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_VOLUME_UP, KeyEvent.KEYCODE_VOLUME_DOWN -> {
|
||||
if (volumeKeyPage(PageDirection.NONE)) {
|
||||
if (volumeKeyPage(PageDirection.NONE, false)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -852,49 +849,52 @@ class ReadBookActivity : BaseReadBookActivity(),
|
||||
if (menuLayoutIsVisible || !AppConfig.mouseWheelPage) {
|
||||
return
|
||||
}
|
||||
keyPageDebounce(direction, 200L, true)
|
||||
keyPageDebounce(direction, mouseWheel = true, longPress = false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 音量键翻页
|
||||
*/
|
||||
private fun volumeKeyPage(direction: PageDirection): Boolean {
|
||||
private fun volumeKeyPage(direction: PageDirection, longPress: Boolean): Boolean {
|
||||
if (!AppConfig.volumeKeyPage) {
|
||||
return false
|
||||
}
|
||||
if (!AppConfig.volumeKeyPageOnPlay && BaseReadAloudService.isPlay()) {
|
||||
return false
|
||||
}
|
||||
handleKeyPage(direction)
|
||||
handleKeyPage(direction, longPress)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun handleKeyPage(direction: PageDirection) {
|
||||
private fun handleKeyPage(direction: PageDirection, longPress: Boolean) {
|
||||
if (AppConfig.keyPageOnLongPress || direction == PageDirection.NONE) {
|
||||
keyPage(direction)
|
||||
} else {
|
||||
keyPageDebounce(direction)
|
||||
keyPageDebounce(direction, longPress = longPress)
|
||||
}
|
||||
}
|
||||
|
||||
private fun keyPageDebounce(
|
||||
direction: PageDirection,
|
||||
delay: Long = 100L,
|
||||
mouseWheel: Boolean = false
|
||||
mouseWheel: Boolean = false,
|
||||
longPress: Boolean
|
||||
) {
|
||||
handler.removeCallbacks(nextPageRunnable)
|
||||
handler.removeCallbacks(prevPageRunnable)
|
||||
if (!mouseWheel) {
|
||||
val keyPageTime = SystemClock.uptimeMillis()
|
||||
val elapsed = keyPageTime - lastKeyPageTime
|
||||
lastKeyPageTime = keyPageTime
|
||||
if (elapsed < 100) {
|
||||
return
|
||||
}
|
||||
if (longPress) {
|
||||
return
|
||||
}
|
||||
nextPageDebounce.apply {
|
||||
wait = if (mouseWheel) 200L else 600L
|
||||
leading = !mouseWheel
|
||||
trailing = mouseWheel
|
||||
}
|
||||
prevPageDebounce.apply {
|
||||
wait = if (mouseWheel) 200L else 600L
|
||||
leading = !mouseWheel
|
||||
trailing = mouseWheel
|
||||
}
|
||||
when (direction) {
|
||||
PageDirection.NEXT -> handler.postDelayed(nextPageRunnable, delay)
|
||||
PageDirection.PREV -> handler.postDelayed(prevPageRunnable, delay)
|
||||
PageDirection.NEXT -> nextPageDebounce.invoke()
|
||||
PageDirection.PREV -> prevPageDebounce.invoke()
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
121
app/src/main/java/io/legado/app/utils/Debounce.kt
Normal file
121
app/src/main/java/io/legado/app/utils/Debounce.kt
Normal file
@ -0,0 +1,121 @@
|
||||
package io.legado.app.utils
|
||||
|
||||
import android.os.SystemClock
|
||||
import kotlin.math.max
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
open class Debounce<T>(
|
||||
var wait: Long = 0L,
|
||||
var maxWait: Long = -1L,
|
||||
var leading: Boolean = false,
|
||||
var trailing: Boolean = true,
|
||||
private val func: () -> T
|
||||
) {
|
||||
companion object {
|
||||
private val handler by lazy { buildMainHandler() }
|
||||
}
|
||||
|
||||
private var lastCallTime = -1L
|
||||
private var lastInvokeTime = 0L
|
||||
private val maxing get() = maxWait != -1L
|
||||
private var result: T? = null
|
||||
private var hasTimer = false
|
||||
private val timerExpiredRunnable = Runnable {
|
||||
timerExpired()
|
||||
}
|
||||
|
||||
init {
|
||||
maxWait = if (maxing) max(maxWait, wait) else maxWait
|
||||
}
|
||||
|
||||
private fun invokeFunc(time: Long): T {
|
||||
lastInvokeTime = time
|
||||
return func.invoke().also { result = it }
|
||||
}
|
||||
|
||||
private fun startTimer(wait: Long) {
|
||||
hasTimer = true
|
||||
handler.postDelayed(timerExpiredRunnable, wait)
|
||||
}
|
||||
|
||||
private fun cancelTimer() {
|
||||
handler.removeCallbacks(timerExpiredRunnable)
|
||||
}
|
||||
|
||||
private fun leadingEdge(time: Long): T? {
|
||||
lastInvokeTime = time
|
||||
startTimer(wait)
|
||||
return if (leading) invokeFunc(time) else result
|
||||
}
|
||||
|
||||
private fun trailingEdge(time: Long): T? {
|
||||
hasTimer = false
|
||||
return if (trailing) invokeFunc(time) else result
|
||||
}
|
||||
|
||||
private fun remainingWait(time: Long): Long {
|
||||
val timeSinceLastCall = time - lastCallTime
|
||||
val timeSinceLastInvoke = time - lastInvokeTime
|
||||
val timeWaiting = wait - timeSinceLastCall
|
||||
|
||||
return if (maxing) timeWaiting.coerceAtMost(maxWait - timeSinceLastInvoke) else timeWaiting
|
||||
}
|
||||
|
||||
private fun shouldInvoke(time: Long): Boolean {
|
||||
val timeSinceLastCall = time - lastCallTime
|
||||
val timeSinceLastInvoke = time - lastInvokeTime
|
||||
|
||||
return lastCallTime == -1L
|
||||
|| timeSinceLastCall >= wait
|
||||
|| timeSinceLastCall < 0
|
||||
|| maxing && timeSinceLastInvoke >= maxWait
|
||||
}
|
||||
|
||||
private fun timerExpired() {
|
||||
val time = SystemClock.uptimeMillis()
|
||||
if (shouldInvoke(time)) {
|
||||
trailingEdge(time)
|
||||
} else {
|
||||
startTimer(remainingWait(time))
|
||||
}
|
||||
}
|
||||
|
||||
fun cancel() {
|
||||
if (hasTimer) {
|
||||
cancelTimer()
|
||||
}
|
||||
lastInvokeTime = 0
|
||||
lastCallTime = -1L
|
||||
hasTimer = false
|
||||
}
|
||||
|
||||
fun flush(): T? {
|
||||
return if (hasTimer) trailingEdge(SystemClock.uptimeMillis()) else result
|
||||
}
|
||||
|
||||
fun pending(): Boolean = hasTimer
|
||||
|
||||
operator fun invoke(): T? {
|
||||
val time = SystemClock.uptimeMillis()
|
||||
val isInvoking = shouldInvoke(time)
|
||||
|
||||
lastCallTime = time
|
||||
|
||||
if (isInvoking) {
|
||||
if (!hasTimer) {
|
||||
return leadingEdge(lastCallTime)
|
||||
}
|
||||
if (maxing) {
|
||||
startTimer(wait)
|
||||
return invokeFunc(lastCallTime)
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasTimer) {
|
||||
startTimer(wait)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
9
app/src/main/java/io/legado/app/utils/Throttle.kt
Normal file
9
app/src/main/java/io/legado/app/utils/Throttle.kt
Normal file
@ -0,0 +1,9 @@
|
||||
package io.legado.app.utils
|
||||
|
||||
@Suppress("unused")
|
||||
class Throttle<T>(
|
||||
wait: Long = 0L,
|
||||
leading: Boolean = true,
|
||||
trailing: Boolean = true,
|
||||
func: () -> T
|
||||
) : Debounce<T>(wait, wait, leading, trailing, func)
|
Loading…
Reference in New Issue
Block a user