feat: 优化代码

pull/117/head
kunfei 5 years ago
parent ee1f04f42c
commit f800991eeb
  1. 4
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  2. 124
      app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt
  3. 112
      app/src/main/java/io/legado/app/ui/book/read/page/content/BaseContentTextView.kt
  4. 2
      app/src/main/res/layout/view_book_page.xml

@ -34,9 +34,9 @@ import io.legado.app.ui.book.read.config.*
import io.legado.app.ui.book.read.config.BgTextConfigDialog.Companion.BG_COLOR import io.legado.app.ui.book.read.config.BgTextConfigDialog.Companion.BG_COLOR
import io.legado.app.ui.book.read.config.BgTextConfigDialog.Companion.TEXT_COLOR import io.legado.app.ui.book.read.config.BgTextConfigDialog.Companion.TEXT_COLOR
import io.legado.app.ui.book.read.page.ChapterProvider import io.legado.app.ui.book.read.page.ChapterProvider
import io.legado.app.ui.book.read.page.ContentTextView
import io.legado.app.ui.book.read.page.PageView import io.legado.app.ui.book.read.page.PageView
import io.legado.app.ui.book.read.page.TextPageFactory import io.legado.app.ui.book.read.page.TextPageFactory
import io.legado.app.ui.book.read.page.content.BaseContentTextView
import io.legado.app.ui.book.read.page.delegate.PageDelegate import io.legado.app.ui.book.read.page.delegate.PageDelegate
import io.legado.app.ui.book.source.edit.BookSourceEditActivity import io.legado.app.ui.book.source.edit.BookSourceEditActivity
import io.legado.app.ui.changesource.ChangeSourceDialog import io.legado.app.ui.changesource.ChangeSourceDialog
@ -58,7 +58,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_boo
View.OnTouchListener, View.OnTouchListener,
PageView.CallBack, PageView.CallBack,
TextActionMenu.CallBack, TextActionMenu.CallBack,
BaseContentTextView.CallBack, ContentTextView.CallBack,
ReadMenu.CallBack, ReadMenu.CallBack,
ReadAloudDialog.CallBack, ReadAloudDialog.CallBack,
ChangeSourceDialog.CallBack, ChangeSourceDialog.CallBack,

@ -1,14 +1,45 @@
package io.legado.app.ui.book.read.page.content package io.legado.app.ui.book.read.page
import android.content.Context import android.content.Context
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet import android.util.AttributeSet
import io.legado.app.ui.book.read.page.ChapterProvider import android.view.View
import io.legado.app.R
import io.legado.app.constant.PreferKey
import io.legado.app.help.ReadBookConfig
import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.book.read.page.entities.TextChar
import io.legado.app.ui.book.read.page.entities.TextPage import io.legado.app.ui.book.read.page.entities.TextPage
import io.legado.app.utils.activity
import io.legado.app.utils.getCompatColor
import io.legado.app.utils.getPrefBoolean
class ContentTextView(context: Context, attrs: AttributeSet?) : class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
BaseContentTextView(context, attrs) { var selectAble = context.getPrefBoolean(PreferKey.textSelectAble)
var upView: ((TextPage) -> Unit)? = null
private val selectedPaint by lazy {
Paint().apply {
color = context.getCompatColor(R.color.btn_bg_press_2)
style = Paint.Style.FILL
}
}
private var callBack: CallBack
private var selectLineStart = 0
private var selectCharStart = 0
private var selectLineEnd = 0
private var selectCharEnd = 0
private var textPage: TextPage = TextPage()
//滚动参数
private val pageFactory: TextPageFactory get() = callBack.pageFactory
private val maxScrollOffset = 100f
private var pageOffset = 0f
init {
callBack = activity as CallBack
contentDescription = textPage.text
}
fun setContent(textPage: TextPage) { fun setContent(textPage: TextPage) {
this.textPage = textPage this.textPage = textPage
@ -16,21 +47,26 @@ class ContentTextView(context: Context, attrs: AttributeSet?) :
invalidate() invalidate()
} }
override fun drawHorizontalPage(canvas: Canvas) { override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
textPage.textLines.forEach { textLine -> super.onSizeChanged(w, h, oldw, oldh)
drawChars( ChapterProvider.viewWidth = w
canvas, ChapterProvider.viewHeight = h
textLine.textChars, ChapterProvider.upSize()
textLine.lineTop, textPage.format()
textLine.lineBase,
textLine.lineBottom,
textLine.isTitle,
textLine.isReadAloud
)
}
} }
override fun drawScrollPage(canvas: Canvas) { override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.clipRect(
ChapterProvider.paddingLeft,
ChapterProvider.paddingTop,
ChapterProvider.visibleRight,
ChapterProvider.visibleBottom
)
drawPage(canvas)
}
private fun drawPage(canvas: Canvas) {
val mPageOffset = pageOffset val mPageOffset = pageOffset
textPage.textLines.forEach { textLine -> textPage.textLines.forEach { textLine ->
val lineTop = textLine.lineTop + mPageOffset val lineTop = textLine.lineTop + mPageOffset
@ -46,6 +82,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) :
textLine.isReadAloud textLine.isReadAloud
) )
} }
if (!ReadBookConfig.isScroll) {
return
}
val nextPage = pageFactory.nextPage val nextPage = pageFactory.nextPage
nextPage.textLines.forEach { textLine -> nextPage.textLines.forEach { textLine ->
val yPy = mPageOffset + textPage.height val yPy = mPageOffset + textPage.height
@ -81,6 +120,26 @@ class ContentTextView(context: Context, attrs: AttributeSet?) :
} }
} }
private fun drawChars(
canvas: Canvas,
textChars: List<TextChar>,
lineTop: Float,
lineBase: Float,
lineBottom: Float,
isTitle: Boolean,
isReadAloud: Boolean
) {
val textPaint = if (isTitle) ChapterProvider.titlePaint else ChapterProvider.contentPaint
textPaint.color =
if (isReadAloud) context.accentColor else ReadBookConfig.durConfig.textColor()
textChars.forEach {
canvas.drawText(it.charData, it.start, lineBase, textPaint)
if (it.selected) {
canvas.drawRect(it.start, lineTop, it.end, lineBottom, selectedPaint)
}
}
}
fun onScroll(mOffset: Float) { fun onScroll(mOffset: Float) {
if (mOffset == 0f) return if (mOffset == 0f) return
var offset = mOffset var offset = mOffset
@ -111,7 +170,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) :
fun selectText(x: Float, y: Float, select: (lineIndex: Int, charIndex: Int) -> Unit) { fun selectText(x: Float, y: Float, select: (lineIndex: Int, charIndex: Int) -> Unit) {
for ((lineIndex, textLine) in textPage.textLines.withIndex()) { for ((lineIndex, textLine) in textPage.textLines.withIndex()) {
if (y > textLine.lineTop && y < textLine.lineBottom) { if (y > textLine.lineTop + pageOffset && y < textLine.lineBottom + pageOffset) {
for ((charIndex, textChar) in textLine.textChars.withIndex()) { for ((charIndex, textChar) in textLine.textChars.withIndex()) {
if (x > textChar.start && x < textChar.end) { if (x > textChar.start && x < textChar.end) {
textChar.selected = true textChar.selected = true
@ -120,8 +179,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) :
selectCharStart = charIndex selectCharStart = charIndex
selectLineEnd = lineIndex selectLineEnd = lineIndex
selectCharEnd = charIndex selectCharEnd = charIndex
upSelectedStart(textChar.start, textLine.lineBottom) upSelectedStart(textChar.start, textLine.lineBottom + pageOffset)
upSelectedEnd(textChar.end, textLine.lineBottom) upSelectedEnd(textChar.end, textLine.lineBottom + pageOffset)
select(lineIndex, charIndex) select(lineIndex, charIndex)
} }
} }
@ -132,7 +191,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) :
fun selectStartMove(x: Float, y: Float) { fun selectStartMove(x: Float, y: Float) {
for ((lineIndex, textLine) in textPage.textLines.withIndex()) { for ((lineIndex, textLine) in textPage.textLines.withIndex()) {
if (y > textLine.lineTop && y < textLine.lineBottom) { if (y > textLine.lineTop + pageOffset && y < textLine.lineBottom + pageOffset) {
for ((charIndex, textChar) in textLine.textChars.withIndex()) { for ((charIndex, textChar) in textLine.textChars.withIndex()) {
if (x > textChar.start && x < textChar.end) { if (x > textChar.start && x < textChar.end) {
if (selectLineStart != lineIndex || selectCharStart != charIndex) { if (selectLineStart != lineIndex || selectCharStart != charIndex) {
@ -154,19 +213,19 @@ class ContentTextView(context: Context, attrs: AttributeSet?) :
selectCharStart = charIndex selectCharStart = charIndex
val textLine = textPage.textLines[lineIndex] val textLine = textPage.textLines[lineIndex]
val textChar = textLine.textChars[charIndex] val textChar = textLine.textChars[charIndex]
upSelectedStart(textChar.start, textLine.lineBottom) upSelectedStart(textChar.start, textLine.lineBottom + pageOffset)
upSelectChars(textPage) upSelectChars(textPage)
} }
fun selectEndMove(x: Float, y: Float) { fun selectEndMove(x: Float, y: Float) {
for ((lineIndex, textLine) in textPage.textLines.withIndex()) { for ((lineIndex, textLine) in textPage.textLines.withIndex()) {
if (y > textLine.lineTop && y < textLine.lineBottom) { if (y > textLine.lineTop + pageOffset && y < textLine.lineBottom + pageOffset) {
for ((charIndex, textChar) in textLine.textChars.withIndex()) { for ((charIndex, textChar) in textLine.textChars.withIndex()) {
if (x > textChar.start && x < textChar.end) { if (x > textChar.start && x < textChar.end) {
if (selectLineEnd != lineIndex || selectCharEnd != charIndex) { if (selectLineEnd != lineIndex || selectCharEnd != charIndex) {
selectLineEnd = lineIndex selectLineEnd = lineIndex
selectCharEnd = charIndex selectCharEnd = charIndex
upSelectedEnd(textChar.end, textLine.lineBottom) upSelectedEnd(textChar.end, textLine.lineBottom + pageOffset)
upSelectChars(textPage) upSelectChars(textPage)
} }
break break
@ -182,7 +241,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) :
selectCharEnd = charIndex selectCharEnd = charIndex
val textLine = textPage.textLines[lineIndex] val textLine = textPage.textLines[lineIndex]
val textChar = textLine.textChars[charIndex] val textChar = textLine.textChars[charIndex]
upSelectedEnd(textChar.end, textLine.lineBottom) upSelectedEnd(textChar.end, textLine.lineBottom + pageOffset)
upSelectChars(textPage) upSelectChars(textPage)
} }
@ -204,6 +263,14 @@ class ContentTextView(context: Context, attrs: AttributeSet?) :
invalidate() invalidate()
} }
private fun upSelectedStart(x: Float, y: Float) {
callBack.upSelectedStart(x, y + callBack.headerHeight)
}
private fun upSelectedEnd(x: Float, y: Float) {
callBack.upSelectedEnd(x, y + callBack.headerHeight)
}
fun cancelSelect() { fun cancelSelect() {
textPage.textLines.forEach { textLine -> textPage.textLines.forEach { textLine ->
textLine.textChars.forEach { textLine.textChars.forEach {
@ -242,4 +309,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) :
return stringBuilder.toString() return stringBuilder.toString()
} }
interface CallBack {
fun upSelectedStart(x: Float, y: Float)
fun upSelectedEnd(x: Float, y: Float)
fun onCancelSelect()
val headerHeight: Int
val pageFactory: TextPageFactory
}
} }

@ -1,112 +0,0 @@
package io.legado.app.ui.book.read.page.content
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import io.legado.app.R
import io.legado.app.constant.PreferKey
import io.legado.app.help.ReadBookConfig
import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.book.read.page.ChapterProvider
import io.legado.app.ui.book.read.page.TextPageFactory
import io.legado.app.ui.book.read.page.entities.TextChar
import io.legado.app.ui.book.read.page.entities.TextPage
import io.legado.app.utils.activity
import io.legado.app.utils.getCompatColor
import io.legado.app.utils.getPrefBoolean
abstract class BaseContentTextView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
var selectAble = context.getPrefBoolean(PreferKey.textSelectAble)
var upView: ((TextPage) -> Unit)? = null
private val selectedPaint by lazy {
Paint().apply {
color = context.getCompatColor(R.color.btn_bg_press_2)
style = Paint.Style.FILL
}
}
protected var callBack: CallBack
protected var selectLineStart = 0
protected var selectCharStart = 0
protected var selectLineEnd = 0
protected var selectCharEnd = 0
protected var textPage: TextPage = TextPage()
//滚动参数
protected val pageFactory: TextPageFactory get() = callBack.pageFactory
protected val maxScrollOffset = 100f
protected var pageOffset = 0f
init {
callBack = activity as CallBack
contentDescription = textPage.text
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
ChapterProvider.viewWidth = w
ChapterProvider.viewHeight = h
ChapterProvider.upSize()
textPage.format()
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.clipRect(
ChapterProvider.paddingLeft,
ChapterProvider.paddingTop,
ChapterProvider.visibleRight,
ChapterProvider.visibleBottom
)
if (ReadBookConfig.isScroll) {
drawScrollPage(canvas)
} else {
drawHorizontalPage(canvas)
}
}
protected abstract fun drawScrollPage(canvas: Canvas)
protected abstract fun drawHorizontalPage(canvas: Canvas)
protected fun drawChars(
canvas: Canvas,
textChars: List<TextChar>,
lineTop: Float,
lineBase: Float,
lineBottom: Float,
isTitle: Boolean,
isReadAloud: Boolean
) {
val textPaint = if (isTitle) ChapterProvider.titlePaint else ChapterProvider.contentPaint
textPaint.color =
if (isReadAloud) context.accentColor else ReadBookConfig.durConfig.textColor()
textChars.forEach {
canvas.drawText(it.charData, it.start, lineBase, textPaint)
if (it.selected) {
canvas.drawRect(it.start, lineTop, it.end, lineBottom, selectedPaint)
}
}
}
protected fun upSelectedStart(x: Float, y: Float) {
callBack.upSelectedStart(x, y + callBack.headerHeight)
}
protected fun upSelectedEnd(x: Float, y: Float) {
callBack.upSelectedEnd(x, y + callBack.headerHeight)
}
interface CallBack {
fun upSelectedStart(x: Float, y: Float)
fun upSelectedEnd(x: Float, y: Float)
fun onCancelSelect()
val headerHeight: Int
val pageFactory: TextPageFactory
}
}

@ -32,7 +32,7 @@
android:background="@color/divider" android:background="@color/divider"
android:visibility="invisible" /> android:visibility="invisible" />
<io.legado.app.ui.book.read.page.content.ContentTextView <io.legado.app.ui.book.read.page.ContentTextView
android:id="@+id/content_text_view" android:id="@+id/content_text_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"

Loading…
Cancel
Save