Horis 2 лет назад
Родитель
Сommit
557c32c834

+ 41 - 7
app/src/main/java/io/legado/app/model/ReadBook.kt

@@ -19,7 +19,9 @@ import io.legado.app.model.localBook.TextFile
 import io.legado.app.model.webBook.WebBook
 import io.legado.app.service.BaseReadAloudService
 import io.legado.app.ui.book.read.page.entities.TextChapter
+import io.legado.app.ui.book.read.page.entities.TextPage
 import io.legado.app.ui.book.read.page.provider.ChapterProvider
+import io.legado.app.ui.book.read.page.provider.LayoutProgressListener
 import io.legado.app.utils.stackTraceStr
 import io.legado.app.utils.toastOnUi
 import kotlinx.coroutines.CoroutineScope
@@ -214,6 +216,7 @@ object ReadBook : CoroutineScope by MainScope() {
             durChapterPos = 0
             durChapterIndex++
             prevTextChapter?.cancelLayout()
+            curTextChapter?.setProgressListener(null)
             prevTextChapter = curTextChapter
             curTextChapter = nextTextChapter
             nextTextChapter = null
@@ -230,7 +233,7 @@ object ReadBook : CoroutineScope by MainScope() {
             callBack?.upMenuView()
             AppLog.putDebug("moveToNextChapter-curPageChanged()")
             curPageChanged()
-            curTextChapter?.let { callBack?.onCurrentTextChapterChanged(it) }
+            curTextChapter?.let { callBack?.onCurrentTextChapterChanged(it, upContent) }
             return true
         } else {
             AppLog.putDebug("跳转下一章失败,没有下一章")
@@ -247,6 +250,7 @@ object ReadBook : CoroutineScope by MainScope() {
             durChapterPos = if (toLast) prevTextChapter?.lastReadLength ?: Int.MAX_VALUE else 0
             durChapterIndex--
             nextTextChapter?.cancelLayout()
+            curTextChapter?.setProgressListener(null)
             nextTextChapter = curTextChapter
             curTextChapter = prevTextChapter
             prevTextChapter = null
@@ -260,7 +264,7 @@ object ReadBook : CoroutineScope by MainScope() {
             saveRead()
             callBack?.upMenuView()
             curPageChanged()
-            curTextChapter?.let { callBack?.onCurrentTextChapterChanged(it) }
+            curTextChapter?.let { callBack?.onCurrentTextChapterChanged(it, upContent) }
             return true
         } else {
             return false
@@ -495,24 +499,52 @@ object ReadBook : CoroutineScope by MainScope() {
             when (val offset = chapter.index - durChapterIndex) {
                 0 -> {
                     curTextChapter?.cancelLayout()
+                    curTextChapter?.setProgressListener(null)
                     curTextChapter = textChapter
-                    if (upContent) callBack?.upContent(offset, resetPageOffset)
+                    if (textChapter.isCompleted) {
+                        if (upContent) callBack?.upContent(offset, resetPageOffset)
+                    } else if (resetPageOffset) {
+                        callBack?.resetPageOffset()
+                    }
                     callBack?.upMenuView()
                     curPageChanged()
                     callBack?.contentLoadFinish()
-                    callBack?.onCurrentTextChapterChanged(textChapter)
+                    callBack?.onCurrentTextChapterChanged(textChapter, upContent)
                 }
 
                 -1 -> {
                     prevTextChapter?.cancelLayout()
                     prevTextChapter = textChapter
-                    if (upContent) callBack?.upContent(offset, resetPageOffset)
+                    if (upContent) {
+                        if (textChapter.isCompleted) {
+                            callBack?.upContent(offset, resetPageOffset)
+                        } else {
+                            textChapter.setProgressListener(object : LayoutProgressListener {
+                                override fun onLayoutCompleted() {
+                                    callBack?.upContent(offset, resetPageOffset)
+                                }
+                            })
+                        }
+                    }
                 }
 
                 1 -> {
                     nextTextChapter?.cancelLayout()
                     nextTextChapter = textChapter
-                    if (upContent) callBack?.upContent(offset, resetPageOffset)
+                    if (upContent) {
+                        if (textChapter.isCompleted) {
+                            callBack?.upContent(offset, resetPageOffset)
+                        } else {
+                            textChapter.setProgressListener(object : LayoutProgressListener {
+                                override fun onLayoutPageCompleted(index: Int, page: TextPage) {
+                                    if (index > 1) {
+                                        return
+                                    }
+                                    callBack?.upContent(offset, resetPageOffset)
+                                }
+                            })
+                        }
+                    }
                 }
             }
             Unit
@@ -650,7 +682,9 @@ object ReadBook : CoroutineScope by MainScope() {
 
         fun notifyBookChanged()
 
-        fun onCurrentTextChapterChanged(textChapter: TextChapter)
+        fun onCurrentTextChapterChanged(textChapter: TextChapter, upContent: Boolean = true)
+
+        fun resetPageOffset()
     }
 
 }

+ 35 - 2
app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt

@@ -126,6 +126,7 @@ import kotlinx.coroutines.Job
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
+import kotlin.math.max
 
 /**
  * 阅读界面
@@ -233,6 +234,7 @@ class ReadBookActivity : BaseReadBookActivity(),
             binding.readMenu.upSeekBar()
         }
     }
+    private var upContent = true
 
     //恢复跳转前进度对话框的交互结果
     private var confirmRestoreProcess: Boolean? = null
@@ -936,7 +938,9 @@ class ReadBookActivity : BaseReadBookActivity(),
     ) {
         lifecycleScope.launch {
             binding.readView.upContent(relativePosition, resetPageOffset)
-            upSeekBarProgress()
+            if (relativePosition == 0) {
+                upSeekBarProgress()
+            }
             loadStates = false
             success?.invoke()
         }
@@ -1369,16 +1373,41 @@ class ReadBookActivity : BaseReadBookActivity(),
         binding.readView.autoPager.resume()
     }
 
-    override fun onCurrentTextChapterChanged(textChapter: TextChapter) {
+    override fun onCurrentTextChapterChanged(textChapter: TextChapter, upContent: Boolean) {
+        this.upContent = upContent
         textChapter.setProgressListener(this)
     }
 
     override fun onLayoutPageCompleted(index: Int, page: TextPage) {
         upSeekBarThrottle.invoke()
+        if (upContent) {
+            val line = page.lines.first()
+            val durChapterPos = ReadBook.durChapterPos
+            val startPos = line.chapterPosition
+            val endPos = startPos + line.charSize
+            if (durChapterPos in startPos..<endPos) {
+                runOnUiThread {
+                    binding.readView.upContent(0, resetPageOffset = false)
+                }
+            }
+            if (isScroll) {
+                val pageIndex = ReadBook.durPageIndex
+                if (max(index - 3, 0) < pageIndex) {
+                    runOnUiThread {
+                        binding.readView.upContent(0, resetPageOffset = false)
+                    }
+                }
+            }
+        }
         binding.readView.onLayoutPageCompleted(index, page)
     }
 
     override fun onLayoutCompleted() {
+        if (upContent) {
+            runOnUiThread {
+                binding.readView.upContent(0, resetPageOffset = false)
+            }
+        }
         binding.readView.onLayoutCompleted()
     }
 
@@ -1388,6 +1417,10 @@ class ReadBookActivity : BaseReadBookActivity(),
         binding.readView.onLayoutException(e)
     }
 
+    override fun resetPageOffset() {
+        binding.readView.resetPageOffset()
+    }
+
     /* 全文搜索跳转 */
     private fun skipToSearch(searchResult: SearchResult) {
         val previousResult = binding.searchMenu.previousSearchResult

+ 2 - 25
app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt

@@ -662,34 +662,11 @@ class ReadView(context: Context, attrs: AttributeSet) :
     }
 
     override fun onLayoutPageCompleted(index: Int, page: TextPage) {
-        val line = page.lines.first()
-        val durChapterPos = ReadBook.durChapterPos
-        val startPos = line.chapterPosition
-        val endPos = startPos + line.charSize
-        if (durChapterPos in startPos..<endPos) {
-            post {
-                upContent(resetPageOffset = false)
-            }
-        }
-        if (isScroll) {
-            val pageIndex = ReadBook.durPageIndex
-            if (index - 3 < pageIndex) {
-                post {
-                    upContent(resetPageOffset = false)
-                }
-            }
-        }
         upProgressThrottle.invoke()
     }
 
-    override fun onLayoutCompleted() {
-        post {
-            upContent(resetPageOffset = false)
-        }
-    }
-
-    override fun onLayoutException(e: Throwable) {
-        // no op
+    fun resetPageOffset() {
+        curPage.resetPageOffset()
     }
 
     override val currentChapter: TextChapter?

+ 4 - 2
app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChapter.kt

@@ -266,11 +266,11 @@ data class TextChapter(
         )
     }
 
-    fun setProgressListener(l: LayoutProgressListener) {
+    fun setProgressListener(l: LayoutProgressListener?) {
         if (isCompleted) {
             // no op
         } else if (layout?.exception != null) {
-            l.onLayoutException(layout?.exception!!)
+            l?.onLayoutException(layout?.exception!!)
         } else {
             listener = l
         }
@@ -287,12 +287,14 @@ data class TextChapter(
     }
 
     override fun onLayoutException(e: Throwable) {
+        isCompleted = true
         listener?.onLayoutException(e)
         listener = null
     }
 
     fun cancelLayout() {
         layout?.cancel()
+        isCompleted = true
     }
 
     companion object {

+ 3 - 3
app/src/main/java/io/legado/app/ui/book/read/page/provider/LayoutProgressListener.kt

@@ -7,16 +7,16 @@ interface LayoutProgressListener {
     /**
      * 单页排版完成
      */
-    fun onLayoutPageCompleted(index: Int, page: TextPage)
+    fun onLayoutPageCompleted(index: Int, page: TextPage) {}
 
     /**
      * 全部排版完成
      */
-    fun onLayoutCompleted()
+    fun onLayoutCompleted() {}
 
     /**
      * 排版出现异常
      */
-    fun onLayoutException(e: Throwable)
+    fun onLayoutException(e: Throwable) {}
 
 }

+ 7 - 3
app/src/main/java/io/legado/app/ui/book/read/page/provider/TextChapterLayout.kt

@@ -90,12 +90,12 @@ class TextChapterLayout(
         }
     }
 
-    fun setProgressListener(l: LayoutProgressListener) {
+    fun setProgressListener(l: LayoutProgressListener?) {
         try {
             if (isCompleted) {
                 // no op
             } else if (exception != null) {
-                l.onLayoutException(exception!!)
+                l?.onLayoutException(exception!!)
             } else {
                 listener = l
             }
@@ -141,6 +141,7 @@ class TextChapterLayout(
 
     private fun onException(e: Throwable) {
         if (e is CancellationException) {
+            listener = null
             return
         }
         try {
@@ -280,6 +281,7 @@ class TextChapterLayout(
             textPage.height += endPadding
         }
         textPage.text = stringBuilder.toString()
+        coroutineContext.ensureActive()
         onPageCompleted()
         onCompleted()
     }
@@ -308,6 +310,7 @@ class TextChapterLayout(
                 }
                 textPage.text = stringBuilder.toString().ifEmpty { "本页无文字内容" }
                 stringBuilder.clear()
+                coroutineContext.ensureActive()
                 onPageCompleted()
                 textPages.add(TextPage())
                 durY = 0f
@@ -342,6 +345,7 @@ class TextChapterLayout(
                             }
                             textPage.text = stringBuilder.toString().ifEmpty { "本页无文字内容" }
                             stringBuilder.clear()
+                            coroutineContext.ensureActive()
                             onPageCompleted()
                             textPages.add(TextPage())
                         }
@@ -424,7 +428,6 @@ class TextChapterLayout(
             else -> y
         }
         for (lineIndex in 0 until layout.lineCount) {
-            coroutineContext.ensureActive()
             val textLine = TextLine(isTitle = isTitle)
             if (durY + textHeight > visibleHeight) {
                 val textPage = textPages.last()
@@ -438,6 +441,7 @@ class TextChapterLayout(
                         textPage.leftLineSize = textPage.lineSize
                     }
                     textPage.text = stringBuilder.toString()
+                    coroutineContext.ensureActive()
                     onPageCompleted()
                     //新建页面
                     textPages.add(TextPage())