pull/2405/head
Horis 2 years ago
parent b08789e996
commit 734bf8416a
  1. 26
      app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt
  2. 8
      app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt
  3. 6
      app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt
  4. 39
      app/src/main/java/io/legado/app/ui/book/read/page/delegate/ScrollPageDelegate.kt
  5. 35
      app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt
  6. 4
      app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt
  7. 8
      app/src/main/res/layout-land/activity_book_info.xml

@ -46,6 +46,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
val selectEnd = TextPos(0, 0, 0) val selectEnd = TextPos(0, 0, 0)
var textPage: TextPage = TextPage() var textPage: TextPage = TextPage()
private set private set
var isMainView = false
private var drawVisibleImageOnly = false private var drawVisibleImageOnly = false
private var cacheIncreased = false private var cacheIncreased = false
private val increaseSize = 8 * 1024 * 1024 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) { override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh) super.onSizeChanged(w, h, oldw, oldh)
if (!isMainView) return
ChapterProvider.upViewSize(w, h) ChapterProvider.upViewSize(w, h)
upVisibleRect() upVisibleRect()
textPage.format() 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
}
/** /**
* 选择开始文字 * 选择开始文字
*/ */

@ -337,6 +337,14 @@ class PageView(context: Context) : FrameLayout(context) {
return binding.contentTextView.selectText(x, y - headerHeight, select) 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) { fun selectStartMove(x: Float, y: Float) {
binding.contentTextView.selectStartMove(x, y - headerHeight) binding.contentTextView.selectStartMove(x, y - headerHeight)
} }

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

@ -3,9 +3,12 @@ package io.legado.app.ui.book.read.page.delegate
import android.graphics.Canvas import android.graphics.Canvas
import android.view.MotionEvent import android.view.MotionEvent
import android.view.VelocityTracker 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.ReadView
import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.book.read.page.provider.ChapterProvider
@Suppress("UnnecessaryVariable")
class ScrollPageDelegate(readView: ReadView) : PageDelegate(readView) { class ScrollPageDelegate(readView: ReadView) : PageDelegate(readView) {
// 滑动追踪的时间 // 滑动追踪的时间
@ -102,7 +105,7 @@ class ScrollPageDelegate(readView: ReadView) : PageDelegate(readView) {
return return
} }
readView.setStartPoint(0f, 0f, false) readView.setStartPoint(0f, 0f, false)
startScroll(0, 0, 0, -ChapterProvider.visibleHeight, animationSpeed) startScroll(0, 0, 0, calcNextPageOffset(), animationSpeed)
} }
override fun prevPageByAnim(animationSpeed: Int) { override fun prevPageByAnim(animationSpeed: Int) {
@ -110,6 +113,38 @@ class ScrollPageDelegate(readView: ReadView) : PageDelegate(readView) {
return return
} }
readView.setStartPoint(0f, 0f, false) 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
} }
} }

@ -61,4 +61,39 @@ data class TextLine(
return y > lineTop + relativeOffset return y > lineTop + relativeOffset
&& y < lineBottom + 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
}
} }

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

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

Loading…
Cancel
Save