Horis 3 سال پیش
والد
کامیت
4dcb8a38d0

+ 22 - 28
app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt

@@ -143,7 +143,6 @@ class ReadBookActivity : BaseReadBookActivity(),
         }
     }
     private var menu: Menu? = null
-    private var autoPageJob: Job? = null
     private var backupJob: Job? = null
     private var keepScreenJon: Job? = null
     private var tts: TTS? = null
@@ -173,6 +172,7 @@ class ReadBookActivity : BaseReadBookActivity(),
     private var bookChanged = false
     private var pageChanged = false
     private var reloadContent = false
+    private val autoPageRenderer by lazy { SyncedRenderer { doAutoPage(it) } }
 
     //恢复跳转前进度对话框的交互结果
     private var confirmRestoreProcess: Boolean? = null
@@ -961,7 +961,7 @@ class ReadBookActivity : BaseReadBookActivity(),
     override fun autoPageStop() {
         if (isAutoPage) {
             isAutoPage = false
-            autoPageJob?.cancel()
+            autoPageRenderer.stop()
             binding.readView.invalidate()
             binding.readMenu.setAutoPage(false)
             upScreenTimeOut()
@@ -969,33 +969,27 @@ class ReadBookActivity : BaseReadBookActivity(),
     }
 
     private fun autoPagePlus() {
-        autoPageJob?.cancel()
-        autoPageJob = lifecycleScope.launch {
-            while (isActive) {
-                var delayMillis = ReadBookConfig.autoReadSpeed * 1000L / binding.readView.height
-                var scrollOffset = 1
-                if (delayMillis < 20) {
-                    var delayInt = delayMillis.toInt()
-                    if (delayInt == 0) delayInt = 1
-                    scrollOffset = 20 / delayInt
-                    delayMillis = 20
-                }
-                delay(delayMillis)
-                if (!menuLayoutIsVisible) {
-                    if (binding.readView.isScroll) {
-                        binding.readView.curPage.scroll(-scrollOffset)
-                    } else {
-                        autoPageProgress += scrollOffset
-                        if (autoPageProgress >= binding.readView.height) {
-                            autoPageProgress = 0
-                            if (!binding.readView.fillPage(PageDirection.NEXT)) {
-                                autoPageStop()
-                            }
-                        } else {
-                            binding.readView.invalidate()
-                        }
-                    }
+        autoPageRenderer.start()
+    }
+
+    private fun doAutoPage(frameTime: Double) {
+        if (menuLayoutIsVisible) {
+            return
+        }
+        val readTime = ReadBookConfig.autoReadSpeed * 1000.0
+        val height = binding.readView.height
+        val scrollOffset = (height / readTime * frameTime).toInt().coerceAtLeast(1)
+        if (binding.readView.isScroll) {
+            binding.readView.curPage.scroll(-scrollOffset)
+        } else {
+            autoPageProgress += scrollOffset
+            if (autoPageProgress >= height) {
+                autoPageProgress = 0
+                if (!binding.readView.fillPage(PageDirection.NEXT)) {
+                    autoPageStop()
                 }
+            } else {
+                binding.readView.invalidate()
             }
         }
     }

+ 25 - 0
app/src/main/java/io/legado/app/utils/SyncedRenderer.kt

@@ -0,0 +1,25 @@
+package io.legado.app.utils
+
+import android.view.Choreographer
+
+class SyncedRenderer(val doFrame: (frameTime: Double) -> Unit) {
+
+    private var callback: (Long) -> Unit = {}
+
+    fun start() {
+        var currTime = System.nanoTime() / 1000000.0
+        callback = {
+            val currTimeMs = it / 1000000.0
+            val frameTime = currTimeMs - currTime
+            currTime = currTimeMs
+            doFrame(frameTime)
+            Choreographer.getInstance().postFrameCallback(callback)
+        }
+        Choreographer.getInstance().postFrameCallback(callback)
+    }
+
+    fun stop() {
+        Choreographer.getInstance().removeFrameCallback(callback)
+        callback = {}
+    }
+}