Преглед изворни кода

Merge pull request #2405 from 821938089/little-fix

一些优化
Horis пре 4 година
родитељ
комит
f691c2404e

+ 26 - 0
app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt

@@ -46,6 +46,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
     val selectEnd = TextPos(0, 0, 0)
     var textPage: TextPage = TextPage()
         private set
+    var isMainView = false
     private var drawVisibleImageOnly = false
     private var cacheIncreased = false
     private val increaseSize = 8 * 1024 * 1024
@@ -93,6 +94,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
 
     override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
         super.onSizeChanged(w, h, oldw, oldh)
+        if (!isMainView) return
         ChapterProvider.upViewSize(w, h)
         upVisibleRect()
         textPage.format()
@@ -468,6 +470,30 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
         }
     }
 
+    fun getCurVisiblePage(): TextPage {
+        val visiblePage = TextPage()
+        var relativeOffset: Float
+        for (relativePos in 0..2) {
+            relativeOffset = relativeOffset(relativePos)
+            if (relativePos > 0) {
+                //滚动翻页
+                if (!callBack.isScroll) break
+                if (relativeOffset >= ChapterProvider.visibleHeight) break
+            }
+            val textPage = relativePage(relativePos)
+            for (textLine in textPage.lines) {
+                if (textLine.isVisible(relativeOffset)) {
+                    val visibleLine = textLine.copy().apply {
+                        lineTop += relativeOffset
+                        lineBottom += relativeOffset
+                    }
+                    visiblePage.addLine(visibleLine)
+                }
+            }
+        }
+        return visiblePage
+    }
+
     /**
      * 选择开始文字
      */

+ 8 - 0
app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt

@@ -337,6 +337,14 @@ class PageView(context: Context) : FrameLayout(context) {
         return binding.contentTextView.selectText(x, y - headerHeight, select)
     }
 
+    fun getCurVisiblePage(): TextPage {
+        return binding.contentTextView.getCurVisiblePage()
+    }
+
+    fun markAsMainView() {
+        binding.contentTextView.isMainView = true
+    }
+
     fun selectStartMove(x: Float, y: Float) {
         binding.contentTextView.selectStartMove(x, y - headerHeight)
     }

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

@@ -22,6 +22,7 @@ import io.legado.app.ui.book.read.page.api.DataSource
 import io.legado.app.ui.book.read.page.delegate.*
 import io.legado.app.ui.book.read.page.entities.PageDirection
 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.entities.TextPos
 import io.legado.app.ui.book.read.page.provider.ChapterProvider
 import io.legado.app.ui.book.read.page.provider.TextPageFactory
@@ -104,6 +105,7 @@ class ReadView(context: Context, attrs: AttributeSet) :
         addView(prevPage)
         nextPage.invisible()
         prevPage.invisible()
+        curPage.markAsMainView()
         if (!isInEditMode) {
             upBg()
             setWillNotDraw(false)
@@ -607,6 +609,10 @@ class ReadView(context: Context, attrs: AttributeSet) :
         return curPage.selectedText
     }
 
+    fun getCurVisiblePage(): TextPage {
+        return curPage.getCurVisiblePage()
+    }
+
     override val currentChapter: TextChapter?
         get() {
             return if (callBack.isInitFinish) ReadBook.textChapter(0) else null

+ 37 - 2
app/src/main/java/io/legado/app/ui/book/read/page/delegate/ScrollPageDelegate.kt

@@ -3,9 +3,12 @@ package io.legado.app.ui.book.read.page.delegate
 import android.graphics.Canvas
 import android.view.MotionEvent
 import android.view.VelocityTracker
+import io.legado.app.help.book.isImage
+import io.legado.app.model.ReadBook
 import io.legado.app.ui.book.read.page.ReadView
 import io.legado.app.ui.book.read.page.provider.ChapterProvider
 
+@Suppress("UnnecessaryVariable")
 class ScrollPageDelegate(readView: ReadView) : PageDelegate(readView) {
 
     // 滑动追踪的时间
@@ -102,7 +105,7 @@ class ScrollPageDelegate(readView: ReadView) : PageDelegate(readView) {
             return
         }
         readView.setStartPoint(0f, 0f, false)
-        startScroll(0, 0, 0, -ChapterProvider.visibleHeight, animationSpeed)
+        startScroll(0, 0, 0, calcNextPageOffset(), animationSpeed)
     }
 
     override fun prevPageByAnim(animationSpeed: Int) {
@@ -110,6 +113,38 @@ class ScrollPageDelegate(readView: ReadView) : PageDelegate(readView) {
             return
         }
         readView.setStartPoint(0f, 0f, false)
-        startScroll(0, 0, 0, ChapterProvider.visibleHeight, animationSpeed)
+        startScroll(0, 0, 0, calcPrevPageOffset(), animationSpeed)
+    }
+
+    /**
+     * 计算点击翻页保留一行的滚动距离
+     * 图片页使用可视高度作为滚动距离
+     */
+    private fun calcNextPageOffset(): Int {
+        val visibleHeight = ChapterProvider.visibleHeight
+        if (ReadBook.book?.isImage == true) {
+            return -visibleHeight
+        }
+        val visiblePage = readView.getCurVisiblePage()
+        if (visiblePage.isImageOrEmpty()) {
+            return -visibleHeight
+        }
+        val lastLineTop = visiblePage.lines.last().lineTop.toInt()
+        val offset = lastLineTop - ChapterProvider.paddingTop
+        return -offset
+    }
+
+    private fun calcPrevPageOffset(): Int {
+        val visibleHeight = ChapterProvider.visibleHeight
+        if (ReadBook.book?.isImage == true) {
+            return visibleHeight
+        }
+        val visiblePage = readView.getCurVisiblePage()
+        if (visiblePage.isImageOrEmpty()) {
+            return visibleHeight
+        }
+        val firstLineBottom = visiblePage.lines.first().lineBottom.toInt()
+        val offset = visibleHeight - (firstLineBottom - ChapterProvider.paddingTop)
+        return offset
     }
 }

+ 35 - 0
app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt

@@ -61,4 +61,39 @@ data class TextLine(
         return y > lineTop + relativeOffset
                 && y < lineBottom + relativeOffset
     }
+
+    fun isVisible(relativeOffset: Float): Boolean {
+        val top = lineTop + relativeOffset
+        val bottom = lineBottom + relativeOffset
+        val width = bottom - top
+        val visibleTop = ChapterProvider.paddingTop
+        val visibleBottom = ChapterProvider.visibleBottom
+        val visible = when {
+            // 完全可视
+            top >= visibleTop && bottom <= visibleBottom -> true
+            top <= visibleTop && bottom >= visibleBottom -> true
+            // 上方第一行部分可视
+            top < visibleTop && bottom > visibleTop && bottom < visibleBottom -> {
+                if (isImage) {
+                    true
+                } else {
+                    val visibleRate = (bottom - visibleTop) / width
+                    visibleRate > 0.6
+                }
+            }
+            // 下方第一行部分可视
+            top > visibleTop && top < visibleBottom && bottom > visibleBottom -> {
+                if (isImage) {
+                    true
+                } else {
+                    val visibleRate = (visibleBottom - top) / width
+                    visibleRate > 0.6
+                }
+            }
+            // 不可视
+            else -> false
+        }
+        return visible
+    }
+
 }

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

@@ -230,4 +230,8 @@ data class TextPage(
         }
         return null
     }
+
+    fun isImageOrEmpty(): Boolean {
+        return textLines.all { it.isTitle || it.isImage }
+    }
 }

+ 6 - 2
app/src/main/res/layout-land/activity_book_info.xml

@@ -15,6 +15,12 @@
         app:layout_constraintTop_toTopOf="parent"
         tools:ignore="ImageContrastCheck" />
 
+    <View
+        android:id="@+id/vw_bg"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="#50000000" />
+
     <io.legado.app.ui.widget.TitleBar
         android:id="@+id/title_bar"
         android:layout_width="match_parent"
@@ -24,10 +30,8 @@
         app:themeMode="dark" />
 
     <LinearLayout
-        android:id="@+id/vw_bg"
         android:layout_width="match_parent"
         android:layout_height="0dp"
-        android:background="#50000000"
         android:orientation="horizontal"
         app:layout_constraintTop_toBottomOf="@id/title_bar"
         app:layout_constraintBottom_toBottomOf="parent"