From f800991eeb107fe58a22019897294013f08f09f0 Mon Sep 17 00:00:00 2001 From: kunfei Date: Tue, 25 Feb 2020 12:16:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/read/ReadBookActivity.kt | 4 +- .../page/{content => }/ContentTextView.kt | 124 ++++++++++++++---- .../read/page/content/BaseContentTextView.kt | 112 ---------------- app/src/main/res/layout/view_book_page.xml | 2 +- 4 files changed, 102 insertions(+), 140 deletions(-) rename app/src/main/java/io/legado/app/ui/book/read/page/{content => }/ContentTextView.kt (68%) delete mode 100644 app/src/main/java/io/legado/app/ui/book/read/page/content/BaseContentTextView.kt diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index 7b68d844d..cf88a03dd 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -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.TEXT_COLOR 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.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.source.edit.BookSourceEditActivity import io.legado.app.ui.changesource.ChangeSourceDialog @@ -58,7 +58,7 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo View.OnTouchListener, PageView.CallBack, TextActionMenu.CallBack, - BaseContentTextView.CallBack, + ContentTextView.CallBack, ReadMenu.CallBack, ReadAloudDialog.CallBack, ChangeSourceDialog.CallBack, diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/content/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt similarity index 68% rename from app/src/main/java/io/legado/app/ui/book/read/page/content/ContentTextView.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 4060012af..5f482f8f6 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/content/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -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.graphics.Canvas +import android.graphics.Paint 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.utils.activity +import io.legado.app.utils.getCompatColor +import io.legado.app.utils.getPrefBoolean -class ContentTextView(context: Context, attrs: AttributeSet?) : - BaseContentTextView(context, attrs) { +class ContentTextView(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 + } + } + 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) { this.textPage = textPage @@ -16,21 +47,26 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : invalidate() } - override fun drawHorizontalPage(canvas: Canvas) { - textPage.textLines.forEach { textLine -> - drawChars( - canvas, - textLine.textChars, - textLine.lineTop, - textLine.lineBase, - textLine.lineBottom, - textLine.isTitle, - textLine.isReadAloud - ) - } + 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 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 textPage.textLines.forEach { textLine -> val lineTop = textLine.lineTop + mPageOffset @@ -46,6 +82,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : textLine.isReadAloud ) } + if (!ReadBookConfig.isScroll) { + return + } val nextPage = pageFactory.nextPage nextPage.textLines.forEach { textLine -> val yPy = mPageOffset + textPage.height @@ -81,6 +120,26 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : } } + private fun drawChars( + canvas: Canvas, + textChars: List, + 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) { if (mOffset == 0f) return 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) { 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()) { if (x > textChar.start && x < textChar.end) { textChar.selected = true @@ -120,8 +179,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : selectCharStart = charIndex selectLineEnd = lineIndex selectCharEnd = charIndex - upSelectedStart(textChar.start, textLine.lineBottom) - upSelectedEnd(textChar.end, textLine.lineBottom) + upSelectedStart(textChar.start, textLine.lineBottom + pageOffset) + upSelectedEnd(textChar.end, textLine.lineBottom + pageOffset) select(lineIndex, charIndex) } } @@ -132,7 +191,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : fun selectStartMove(x: Float, y: Float) { 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()) { if (x > textChar.start && x < textChar.end) { if (selectLineStart != lineIndex || selectCharStart != charIndex) { @@ -154,19 +213,19 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : selectCharStart = charIndex val textLine = textPage.textLines[lineIndex] val textChar = textLine.textChars[charIndex] - upSelectedStart(textChar.start, textLine.lineBottom) + upSelectedStart(textChar.start, textLine.lineBottom + pageOffset) upSelectChars(textPage) } fun selectEndMove(x: Float, y: Float) { 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()) { if (x > textChar.start && x < textChar.end) { if (selectLineEnd != lineIndex || selectCharEnd != charIndex) { selectLineEnd = lineIndex selectCharEnd = charIndex - upSelectedEnd(textChar.end, textLine.lineBottom) + upSelectedEnd(textChar.end, textLine.lineBottom + pageOffset) upSelectChars(textPage) } break @@ -182,7 +241,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : selectCharEnd = charIndex val textLine = textPage.textLines[lineIndex] val textChar = textLine.textChars[charIndex] - upSelectedEnd(textChar.end, textLine.lineBottom) + upSelectedEnd(textChar.end, textLine.lineBottom + pageOffset) upSelectChars(textPage) } @@ -204,6 +263,14 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : 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() { textPage.textLines.forEach { textLine -> textLine.textChars.forEach { @@ -242,4 +309,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : 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 + } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/content/BaseContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/content/BaseContentTextView.kt deleted file mode 100644 index 95fd796ea..000000000 --- a/app/src/main/java/io/legado/app/ui/book/read/page/content/BaseContentTextView.kt +++ /dev/null @@ -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, - 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 - } -} \ No newline at end of file diff --git a/app/src/main/res/layout/view_book_page.xml b/app/src/main/res/layout/view_book_page.xml index 325e8a75c..81c9e09d4 100644 --- a/app/src/main/res/layout/view_book_page.xml +++ b/app/src/main/res/layout/view_book_page.xml @@ -32,7 +32,7 @@ android:background="@color/divider" android:visibility="invisible" /> -