feat: 优化代码

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

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