feat: 优化代码

pull/117/head
kunfei 5 years ago
parent 37d5643b8d
commit 4337c773ff
  1. 255
      app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt
  2. 13
      app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt
  3. 39
      app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt

@ -28,8 +28,10 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
} }
private var callBack: CallBack private var callBack: CallBack
private val visibleRect = RectF() private val visibleRect = RectF()
private var selectPageStart = 0
private var selectLineStart = 0 private var selectLineStart = 0
private var selectCharStart = 0 private var selectCharStart = 0
private var selectPageEnd = 0
private var selectLineEnd = 0 private var selectLineEnd = 0
private var selectCharEnd = 0 private var selectCharEnd = 0
private var textPage: TextPage = TextPage() private var textPage: TextPage = TextPage()
@ -69,12 +71,15 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
drawPage(canvas) drawPage(canvas)
} }
/**
* 绘制页面
*/
private fun drawPage(canvas: Canvas) { private fun drawPage(canvas: Canvas) {
val mPageOffset = pageOffset var relativeOffset = relativeOffset(0)
textPage.textLines.forEach { textLine -> textPage.textLines.forEach { textLine ->
val lineTop = textLine.lineTop + mPageOffset val lineTop = textLine.lineTop + relativeOffset
val lineBase = textLine.lineBase + mPageOffset val lineBase = textLine.lineBase + relativeOffset
val lineBottom = textLine.lineBottom + mPageOffset val lineBottom = textLine.lineBottom + relativeOffset
drawChars( drawChars(
canvas, canvas,
textLine.textChars, textLine.textChars,
@ -85,15 +90,14 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
textLine.isReadAloud textLine.isReadAloud
) )
} }
if (!ReadBookConfig.isScroll) { if (!ReadBookConfig.isScroll) return
return //滚动翻页
} val nextPage = relativePage(1)
val nextPage = pageFactory.nextPage relativeOffset = relativeOffset(1)
nextPage.textLines.forEach { textLine -> nextPage.textLines.forEach { textLine ->
val yPy = mPageOffset + textPage.height val lineTop = textLine.lineTop + relativeOffset
val lineTop = textLine.lineTop + yPy val lineBase = textLine.lineBase + relativeOffset
val lineBase = textLine.lineBase + yPy val lineBottom = textLine.lineBottom + relativeOffset
val lineBottom = textLine.lineBottom + yPy
drawChars( drawChars(
canvas, canvas,
textLine.textChars, textLine.textChars,
@ -104,12 +108,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
textLine.isReadAloud textLine.isReadAloud
) )
} }
if (mPageOffset + textPage.height + nextPage.height < ChapterProvider.visibleHeight) { relativeOffset = relativeOffset(2)
pageFactory.nextPagePlus.textLines.forEach { textLine -> if (relativeOffset < ChapterProvider.visibleHeight) {
val yPy = mPageOffset + textPage.height + nextPage.height relativePage(2).textLines.forEach { textLine ->
val lineTop = textLine.lineTop + yPy val lineTop = textLine.lineTop + relativeOffset
val lineBase = textLine.lineBase + yPy val lineBase = textLine.lineBase + relativeOffset
val lineBottom = textLine.lineBottom + yPy val lineBottom = textLine.lineBottom + relativeOffset
drawChars( drawChars(
canvas, canvas,
textLine.textChars, textLine.textChars,
@ -123,6 +127,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
} }
} }
/**
* 绘制文字
*/
private fun drawChars( private fun drawChars(
canvas: Canvas, canvas: Canvas,
textChars: List<TextChar>, textChars: List<TextChar>,
@ -143,6 +150,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
} }
} }
/**
* 滚动事件
*/
fun onScroll(mOffset: Float) { fun onScroll(mOffset: Float) {
if (mOffset == 0f) return if (mOffset == 0f) return
var offset = mOffset var offset = mOffset
@ -171,83 +181,232 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
pageOffset = 0f pageOffset = 0f
} }
fun selectText(x: Float, y: Float, select: (lineIndex: Int, charIndex: Int) -> Unit) { /**
* 选择初始文字
*/
fun selectText(
x: Float,
y: Float,
select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit
) {
if (!visibleRect.contains(x, y)) return if (!visibleRect.contains(x, y)) return
var relativeOffset = relativeOffset(0)
for ((lineIndex, textLine) in textPage.textLines.withIndex()) { for ((lineIndex, textLine) in textPage.textLines.withIndex()) {
if (y > textLine.lineTop + pageOffset && y < textLine.lineBottom + pageOffset) { if (y > textLine.lineTop + relativeOffset && y < textLine.lineBottom + relativeOffset) {
for ((charIndex, textChar) in textLine.textChars.withIndex()) {
if (x > textChar.start && x < textChar.end) {
textChar.selected = true
invalidate()
selectPageStart = 0
selectLineStart = lineIndex
selectCharStart = charIndex
selectPageEnd = 0
selectLineEnd = lineIndex
selectCharEnd = charIndex
upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset)
select(0, lineIndex, charIndex)
return
}
}
return
}
}
if (!ReadBookConfig.isScroll) return
//滚动翻页
relativeOffset = relativeOffset(1)
if (relativeOffset >= ChapterProvider.visibleHeight) return
val nextPage = relativePage(1)
for ((lineIndex, textLine) in nextPage.textLines.withIndex()) {
if (y > textLine.lineTop + relativeOffset && y < textLine.lineBottom + relativeOffset) {
for ((charIndex, textChar) in textLine.textChars.withIndex()) {
if (x > textChar.start && x < textChar.end) {
textChar.selected = true
invalidate()
selectPageStart = 1
selectLineStart = lineIndex
selectCharStart = charIndex
selectPageEnd = 1
selectLineEnd = lineIndex
selectCharEnd = charIndex
upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset)
select(1, lineIndex, charIndex)
return
}
}
return
}
}
relativeOffset = relativeOffset(2)
if (relativeOffset >= ChapterProvider.visibleHeight) return
for ((lineIndex, textLine) in relativePage(2).textLines.withIndex()) {
if (y > textLine.lineTop + relativeOffset && y < textLine.lineBottom + relativeOffset) {
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
invalidate() invalidate()
selectPageStart = 2
selectLineStart = lineIndex selectLineStart = lineIndex
selectCharStart = charIndex selectCharStart = charIndex
selectPageEnd = 2
selectLineEnd = lineIndex selectLineEnd = lineIndex
selectCharEnd = charIndex selectCharEnd = charIndex
upSelectedStart(textChar.start, textLine.lineBottom + pageOffset) upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
upSelectedEnd(textChar.end, textLine.lineBottom + pageOffset) upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset)
select(lineIndex, charIndex) select(2, lineIndex, charIndex)
return
} }
} }
break return
} }
} }
} }
/**
* 开始选择符移动
*/
fun selectStartMove(x: Float, y: Float) { fun selectStartMove(x: Float, y: Float) {
if (!visibleRect.contains(x, y)) return if (!visibleRect.contains(x, y)) return
var relativeOffset = relativeOffset(0)
for ((lineIndex, textLine) in textPage.textLines.withIndex()) { for ((lineIndex, textLine) in textPage.textLines.withIndex()) {
if (y > textLine.lineTop + pageOffset && y < textLine.lineBottom + pageOffset) { if (y > textLine.lineTop + relativeOffset && y < textLine.lineBottom + relativeOffset) {
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) {
selectPageStart = 0
selectLineStart = lineIndex selectLineStart = lineIndex
selectCharStart = charIndex selectCharStart = charIndex
upSelectedStart(textChar.start, textLine.lineBottom + pageOffset) upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
upSelectChars(textPage) upSelectChars(textPage)
} }
break return
} }
} }
break return
} }
} }
if (!ReadBookConfig.isScroll) return
//滚动翻页
relativeOffset = relativeOffset(1)
if (relativeOffset >= ChapterProvider.visibleHeight) return
for ((lineIndex, textLine) in relativePage(1).textLines.withIndex()) {
if (y > textLine.lineTop + relativeOffset && y < textLine.lineBottom + relativeOffset) {
for ((charIndex, textChar) in textLine.textChars.withIndex()) {
if (x > textChar.start && x < textChar.end) {
if (selectLineStart != lineIndex || selectCharStart != charIndex) {
selectPageStart = 1
selectLineStart = lineIndex
selectCharStart = charIndex
upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
upSelectChars(textPage)
} }
return
fun selectStartMoveIndex(lineIndex: Int, charIndex: Int) { }
}
return
}
}
relativeOffset = relativeOffset(2)
if (relativeOffset >= ChapterProvider.visibleHeight) return
for ((lineIndex, textLine) in relativePage(2).textLines.withIndex()) {
if (y > textLine.lineTop + relativeOffset && y < textLine.lineBottom + relativeOffset) {
for ((charIndex, textChar) in textLine.textChars.withIndex()) {
if (x > textChar.start && x < textChar.end) {
if (selectLineStart != lineIndex || selectCharStart != charIndex) {
selectPageStart = 1
selectLineStart = lineIndex selectLineStart = lineIndex
selectCharStart = charIndex selectCharStart = charIndex
val textLine = textPage.textLines[lineIndex] upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset)
val textChar = textLine.textChars[charIndex]
upSelectedStart(textChar.start, textLine.lineBottom + pageOffset)
upSelectChars(textPage) upSelectChars(textPage)
} }
return
}
}
return
}
}
}
/**
* 结束选择符移动
*/
fun selectEndMove(x: Float, y: Float) { fun selectEndMove(x: Float, y: Float) {
if (!visibleRect.contains(x, y)) return if (!visibleRect.contains(x, y)) return
var relativeOffset = relativeOffset(0)
for ((lineIndex, textLine) in textPage.textLines.withIndex()) { for ((lineIndex, textLine) in textPage.textLines.withIndex()) {
if (y > textLine.lineTop + pageOffset && y < textLine.lineBottom + pageOffset) { if (y > textLine.lineTop + relativeOffset && y < textLine.lineBottom + relativeOffset) {
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 + pageOffset) upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset)
upSelectChars(textPage) upSelectChars(textPage)
} }
break return
} }
} }
break return
}
}
if (!ReadBookConfig.isScroll) return
//滚动翻页
relativeOffset = relativeOffset(1)
if (relativeOffset >= ChapterProvider.visibleHeight) return
for ((lineIndex, textLine) in relativePage(1).textLines.withIndex()) {
if (y > textLine.lineTop + relativeOffset && y < textLine.lineBottom + relativeOffset) {
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 + relativeOffset)
upSelectChars(textPage)
}
return
}
}
return
}
}
relativeOffset = relativeOffset(2)
if (relativeOffset >= ChapterProvider.visibleHeight) return
for ((lineIndex, textLine) in relativePage(2).textLines.withIndex()) {
if (y > textLine.lineTop + relativeOffset && y < textLine.lineBottom + relativeOffset) {
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 + relativeOffset)
upSelectChars(textPage)
}
return
}
}
return
} }
} }
} }
fun selectEndMoveIndex(lineIndex: Int, charIndex: Int) { fun selectStartMoveIndex(relativePage: Int, lineIndex: Int, charIndex: Int) {
selectPageStart = relativePage
selectLineStart = lineIndex
selectCharStart = charIndex
val textLine = relativePage(relativePage).textLines[lineIndex]
val textChar = textLine.textChars[charIndex]
upSelectedStart(textChar.start, textLine.lineBottom + relativeOffset(relativePage))
upSelectChars(textPage)
}
fun selectEndMoveIndex(relativePage: Int, lineIndex: Int, charIndex: Int) {
selectPageEnd = relativePage
selectLineEnd = lineIndex selectLineEnd = lineIndex
selectCharEnd = charIndex selectCharEnd = charIndex
val textLine = textPage.textLines[lineIndex] val textLine = relativePage(relativePage).textLines[lineIndex]
val textChar = textLine.textChars[charIndex] val textChar = textLine.textChars[charIndex]
upSelectedEnd(textChar.end, textLine.lineBottom + pageOffset) upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset(relativePage))
upSelectChars(textPage) upSelectChars(textPage)
} }
@ -315,6 +474,22 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
return stringBuilder.toString() return stringBuilder.toString()
} }
private fun relativeOffset(relativePos: Int): Float {
return when (relativePos) {
0 -> pageOffset
1 -> pageOffset + textPage.height
else -> pageOffset + textPage.height + pageFactory.nextPage.height
}
}
private fun relativePage(relativePos: Int): TextPage {
return when (relativePos) {
0 -> textPage
1 -> pageFactory.nextPage
else -> pageFactory.nextPagePlus
}
}
interface CallBack { interface CallBack {
fun upSelectedStart(x: Float, y: Float) fun upSelectedStart(x: Float, y: Float)
fun upSelectedEnd(x: Float, y: Float) fun upSelectedEnd(x: Float, y: Float)

@ -119,7 +119,10 @@ class ContentView(context: Context) : FrameLayout(context) {
content_text_view.selectAble = selectAble content_text_view.selectAble = selectAble
} }
fun selectText(e: MotionEvent, select: (lineIndex: Int, charIndex: Int) -> Unit) { fun selectText(
e: MotionEvent,
select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit
) {
val y = e.y - headerHeight val y = e.y - headerHeight
return content_text_view.selectText(e.x, y, select) return content_text_view.selectText(e.x, y, select)
} }
@ -128,16 +131,16 @@ class ContentView(context: Context) : FrameLayout(context) {
content_text_view.selectStartMove(x, y - headerHeight) content_text_view.selectStartMove(x, y - headerHeight)
} }
fun selectStartMoveIndex(lineIndex: Int, charIndex: Int) { fun selectStartMoveIndex(relativePage: Int, lineIndex: Int, charIndex: Int) {
content_text_view.selectStartMoveIndex(lineIndex, charIndex) content_text_view.selectStartMoveIndex(relativePage, lineIndex, charIndex)
} }
fun selectEndMove(x: Float, y: Float) { fun selectEndMove(x: Float, y: Float) {
content_text_view.selectEndMove(x, y - headerHeight) content_text_view.selectEndMove(x, y - headerHeight)
} }
fun selectEndMoveIndex(lineIndex: Int, charIndex: Int) { fun selectEndMoveIndex(relativePage: Int, lineIndex: Int, charIndex: Int) {
content_text_view.selectEndMoveIndex(lineIndex, charIndex) content_text_view.selectEndMoveIndex(relativePage, lineIndex, charIndex)
} }
fun cancelSelect() { fun cancelSelect() {

@ -67,6 +67,7 @@ abstract class PageDelegate(protected val pageView: PageView) :
var isTextSelected = false var isTextSelected = false
var selectedOnDown = false var selectedOnDown = false
var firstRelativePage = 0
var firstLineIndex: Int = 0 var firstLineIndex: Int = 0
var firstCharIndex: Int = 0 var firstCharIndex: Int = 0
@ -286,23 +287,41 @@ abstract class PageDelegate(protected val pageView: PageView) :
* 长按选择 * 长按选择
*/ */
override fun onLongPress(e: MotionEvent) { override fun onLongPress(e: MotionEvent) {
curPage.selectText(e) { lineIndex, charIndex -> curPage.selectText(e) { relativePage, lineIndex, charIndex ->
isTextSelected = true isTextSelected = true
firstRelativePage = relativePage
firstLineIndex = lineIndex firstLineIndex = lineIndex
firstCharIndex = charIndex firstCharIndex = charIndex
} }
} }
protected fun selectText(event: MotionEvent) { protected fun selectText(event: MotionEvent) {
curPage.selectText(event) { lineIndex, charIndex -> curPage.selectText(event) { relativePage, lineIndex, charIndex ->
if (lineIndex > firstLineIndex when {
|| (lineIndex == firstLineIndex && charIndex > firstCharIndex) relativePage > firstRelativePage -> {
) { curPage.selectStartMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
curPage.selectStartMoveIndex(firstLineIndex, firstCharIndex) curPage.selectEndMoveIndex(relativePage, lineIndex, charIndex)
curPage.selectEndMoveIndex(lineIndex, charIndex) }
} else { relativePage < firstRelativePage -> {
curPage.selectEndMoveIndex(firstLineIndex, firstCharIndex) curPage.selectEndMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
curPage.selectStartMoveIndex(lineIndex, charIndex) curPage.selectStartMoveIndex(relativePage, lineIndex, charIndex)
}
lineIndex > firstLineIndex -> {
curPage.selectStartMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
curPage.selectEndMoveIndex(relativePage, lineIndex, charIndex)
}
lineIndex < firstLineIndex -> {
curPage.selectEndMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
curPage.selectStartMoveIndex(relativePage, lineIndex, charIndex)
}
charIndex > firstCharIndex -> {
curPage.selectStartMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
curPage.selectEndMoveIndex(relativePage, lineIndex, charIndex)
}
else -> {
curPage.selectEndMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
curPage.selectStartMoveIndex(relativePage, lineIndex, charIndex)
}
} }
} }
} }

Loading…
Cancel
Save