基本完成了按钮的UI设计,暂未实装按钮触摸事件

pull/2250/head
Seidko 2 years ago
parent 1f90bf8d8c
commit b21659c23a
  1. 2
      app/src/main/java/io/legado/app/help/config/ReadBookConfig.kt
  2. 3
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  3. 80
      app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt
  4. 3
      app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt
  5. 1
      app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt
  6. 7
      app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt
  7. 37
      app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt
  8. 2
      app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt
  9. 7
      app/src/main/res/menu/book_read.xml

@ -449,7 +449,7 @@ object ReadBookConfig {
var letterSpacing: Float = 0.1f,//字间距 var letterSpacing: Float = 0.1f,//字间距
var lineSpacingExtra: Int = 12,//行间距 var lineSpacingExtra: Int = 12,//行间距
var paragraphSpacing: Int = 2,//段距 var paragraphSpacing: Int = 2,//段距
var titleMode: Int = 0,//标题居中 var titleMode: Int = 0,//标题位置 0:居左 1:居中 2:隐藏
var titleSize: Int = 0, var titleSize: Int = 0,
var titleTopSpacing: Int = 0, var titleTopSpacing: Int = 0,
var titleBottomSpacing: Int = 0, var titleBottomSpacing: Int = 0,

@ -355,6 +355,9 @@ class ReadBookActivity : BaseReadBookActivity(),
menu?.findItem(R.id.menu_re_segment)?.isChecked = it.getReSegment() menu?.findItem(R.id.menu_re_segment)?.isChecked = it.getReSegment()
ReadBook.loadContent(false) ReadBook.loadContent(false)
} }
R.id.menu_enable_review -> ReadBook.book?.let {
// TODO
}
R.id.menu_page_anim -> showPageAnimConfig { R.id.menu_page_anim -> showPageAnimConfig {
binding.readView.upPageAnim() binding.readView.upPageAnim()
ReadBook.loadContent(false) ReadBook.loadContent(false)

@ -4,6 +4,8 @@ import android.content.Context
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Paint import android.graphics.Paint
import android.graphics.RectF import android.graphics.RectF
import android.text.StaticLayout
import android.text.TextPaint
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import io.legado.app.R import io.legado.app.R
@ -150,6 +152,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
ChapterProvider.contentPaint ChapterProvider.contentPaint
} }
val textColor = if (textLine.isReadAloud) context.accentColor else ReadBookConfig.textColor val textColor = if (textLine.isReadAloud) context.accentColor else ReadBookConfig.textColor
val linePaint = Paint()
linePaint.strokeWidth = textPaint.textSize / 21
linePaint.color = textColor
val reviewCountPaint = TextPaint()
reviewCountPaint.textSize = textPaint.textSize * 0.6F
reviewCountPaint.color = textColor
textLine.textChars.forEach { textLine.textChars.forEach {
if (it.isImage) { if (it.isImage) {
drawImage(canvas, textPage, textLine, it, lineTop, lineBottom) drawImage(canvas, textPage, textLine, it, lineTop, lineBottom)
@ -158,7 +166,74 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
if (it.isSearchResult) { if (it.isSearchResult) {
textPaint.color = context.accentColor textPaint.color = context.accentColor
} }
canvas.drawText(it.charData, it.start, lineBase, textPaint) if (it.charData == "\uD83D\uDCAC" && it.isLineEnd) {
if (textLine.reviewCount <= 0) return@forEach
canvas.drawLine(
it.start,
lineBase - textPaint.textSize * 2 / 5,
it.start + textPaint.textSize / 6,
lineBase - textPaint.textSize / 4,
linePaint
)
canvas.drawLine(
it.start,
lineBase - textPaint.textSize * 0.38F,
it.start + textPaint.textSize / 6,
lineBase - textPaint.textSize * 0.55F,
linePaint
)
canvas.drawLine(
it.start + textPaint.textSize / 6,
lineBase - textPaint.textSize / 4,
it.start + textPaint.textSize / 6,
lineBase,
linePaint
)
canvas.drawLine(
it.start + textPaint.textSize / 6,
lineBase - textPaint.textSize * 0.55F,
it.start + textPaint.textSize / 6,
lineBase - textPaint.textSize * 0.8F,
linePaint
)
canvas.drawLine(
it.start + textPaint.textSize / 6,
lineBase,
it.start + textPaint.textSize * 1.6F,
lineBase,
linePaint
)
canvas.drawLine(
it.start + textPaint.textSize / 6,
lineBase - textPaint.textSize * 0.8F,
it.start + textPaint.textSize * 1.6F,
lineBase - textPaint.textSize * 0.8F,
linePaint
)
canvas.drawLine(
it.start + textPaint.textSize * 1.6F,
lineBase - textPaint.textSize * 0.8F,
it.start + textPaint.textSize * 1.6F,
lineBase,
linePaint
)
if (textLine.reviewCount < 100) canvas.drawText(
textLine.reviewCount.toString(),
it.start + textPaint.textSize * 0.87F -
StaticLayout.getDesiredWidth(
textLine.reviewCount.toString(),
reviewCountPaint
) / 2,
lineBase - textPaint.textSize / 6,
reviewCountPaint
)
else canvas.drawText(
"99+",
it.start + textPaint.textSize * 0.35F,
lineBase - textPaint.textSize / 6,
reviewCountPaint
)
} else canvas.drawText(it.charData, it.start, lineBase, textPaint)
} }
if (it.selected) { if (it.selected) {
canvas.drawRect(it.start, lineTop, it.end, lineBottom, selectedPaint) canvas.drawRect(it.start, lineTop, it.end, lineBottom, selectedPaint)
@ -276,6 +351,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
callBack.onImageLongPress(x, y, textChar.charData) callBack.onImageLongPress(x, y, textChar.charData)
} else { } else {
if (!selectAble) return@touch if (!selectAble) return@touch
if (textChar.charData == "\uD83D\uDCAC" && textChar.isLineEnd) return@touch
textChar.selected = true textChar.selected = true
invalidate() invalidate()
select(relativePos, lineIndex, charIndex) select(relativePos, lineIndex, charIndex)
@ -292,6 +368,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit, select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit,
) { ) {
touch(x, y) { _, relativePos, _, lineIndex, _, charIndex, textChar -> touch(x, y) { _, relativePos, _, lineIndex, _, charIndex, textChar ->
if (textChar.charData == "\uD83D\uDCAC" && textChar.isLineEnd) return@touch
textChar.selected = true textChar.selected = true
invalidate() invalidate()
select(relativePos, lineIndex, charIndex) select(relativePos, lineIndex, charIndex)
@ -415,6 +492,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
textPos.lineIndex = lineIndex textPos.lineIndex = lineIndex
for ((charIndex, textChar) in textLine.textChars.withIndex()) { for ((charIndex, textChar) in textLine.textChars.withIndex()) {
textPos.charIndex = charIndex textPos.charIndex = charIndex
if (textChar.charData == "\uD83D\uDCAC" && textChar.isLineEnd) continue
textChar.selected = textChar.selected =
textPos.compare(selectStart) >= 0 && textPos.compare(selectEnd) <= 0 textPos.compare(selectStart) >= 0 && textPos.compare(selectEnd) <= 0
textChar.isSearchResult = textChar.selected && callBack.isSelectingSearchResult textChar.isSearchResult = textChar.selected && callBack.isSelectingSearchResult

@ -6,7 +6,8 @@ data class TextChar(
var end: Float, var end: Float,
var selected: Boolean = false, var selected: Boolean = false,
var isImage: Boolean = false, var isImage: Boolean = false,
var isSearchResult: Boolean = false var isSearchResult: Boolean = false,
var isLineEnd: Boolean = false
) { ) {
fun isTouch(x: Float): Boolean { fun isTouch(x: Float): Boolean {

@ -8,6 +8,7 @@ import io.legado.app.utils.textHeight
data class TextLine( data class TextLine(
var text: String = "", var text: String = "",
val textChars: ArrayList<TextChar> = arrayListOf(), val textChars: ArrayList<TextChar> = arrayListOf(),
val reviewCount: Int = 0,
var lineTop: Float = 0f, var lineTop: Float = 0f,
var lineBase: Float = 0f, var lineBase: Float = 0f,
var lineBottom: Float = 0f, var lineBottom: Float = 0f,

@ -111,7 +111,12 @@ data class TextPage(
val cw = StaticLayout.getDesiredWidth(char, ChapterProvider.contentPaint) val cw = StaticLayout.getDesiredWidth(char, ChapterProvider.contentPaint)
val x1 = x + cw val x1 = x + cw
textLine.textChars.add( textLine.textChars.add(
TextChar(char, start = x, end = x1) TextChar(
char,
start = x,
end = x1,
isLineEnd = textLine.text.length - 1 == i
)
) )
x = x1 x = x1
} }

@ -116,7 +116,13 @@ object ChapterProvider {
if (ReadBookConfig.titleMode != 2) { if (ReadBookConfig.titleMode != 2) {
displayTitle.splitNotBlank("\n").forEach { text -> displayTitle.splitNotBlank("\n").forEach { text ->
setTypeText( setTypeText(
book, absStartX, durY, text, textPages, stringBuilder, titlePaint, book,
absStartX,
durY,
text + "\ud83d\udcac",
textPages,
stringBuilder,
titlePaint,
isTitle = true, isTitle = true,
isTitleWithNoContent = contents.isEmpty(), isTitleWithNoContent = contents.isEmpty(),
isVolumeTitle = bookChapter.isVolume isVolumeTitle = bookChapter.isVolume
@ -171,7 +177,13 @@ object ChapterProvider {
val text = content.substring(start, content.length) val text = content.substring(start, content.length)
if (text.isNotBlank()) { if (text.isNotBlank()) {
setTypeText( setTypeText(
book, absStartX, durY, text, textPages, stringBuilder, contentPaint book,
absStartX,
durY,
text + "\ud83d\udcac",
textPages,
stringBuilder,
contentPaint
).let { ).let {
absStartX = it.first absStartX = it.first
durY = it.second durY = it.second
@ -276,9 +288,8 @@ object ChapterProvider {
srcList: LinkedList<String>? = null srcList: LinkedList<String>? = null
): Pair<Int, Float> { ): Pair<Int, Float> {
var absStartX = x var absStartX = x
val layout = if (ReadBookConfig.useZhLayout) { val layout = if (ReadBookConfig.useZhLayout) ZhLayout(text, textPaint, visibleWidth)
ZhLayout(text, textPaint, visibleWidth) else StaticLayout(
} else StaticLayout(
text, textPaint, visibleWidth, Layout.Alignment.ALIGN_NORMAL, 0f, 0f, true text, textPaint, visibleWidth, Layout.Alignment.ALIGN_NORMAL, 0f, 0f, true
) )
var durY = when { var durY = when {
@ -398,10 +409,15 @@ object ChapterProvider {
} }
val bodyIndent = ReadBookConfig.paragraphIndent val bodyIndent = ReadBookConfig.paragraphIndent
val icw = StaticLayout.getDesiredWidth(bodyIndent, textPaint) / bodyIndent.length val icw = StaticLayout.getDesiredWidth(bodyIndent, textPaint) / bodyIndent.length
bodyIndent.toStringArray().forEach { char -> for ((index, char) in bodyIndent.toStringArray().withIndex()) {
val x1 = x + icw val x1 = x + icw
textLine.textChars.add( textLine.textChars.add(
TextChar(charData = char, start = absStartX + x, end = absStartX + x1) TextChar(
charData = char,
start = absStartX + x,
end = absStartX + x1,
isLineEnd = bodyIndent.length - 1 == index
)
) )
x = x1 x = x1
} }
@ -492,7 +508,8 @@ object ChapterProvider {
TextChar( TextChar(
charData = char, charData = char,
start = absStartX + xStart, start = absStartX + xStart,
end = absStartX + xEnd end = absStartX + xEnd,
isLineEnd = true
) )
) )
} }
@ -612,12 +629,12 @@ object ChapterProvider {
* 更新绘制尺寸 * 更新绘制尺寸
*/ */
fun upLayout() { fun upLayout() {
when(AppConfig.doublePageHorizontal){ when (AppConfig.doublePageHorizontal) {
"0" -> doublePage = false "0" -> doublePage = false
"1" -> doublePage = true "1" -> doublePage = true
"2" -> { "2" -> {
doublePage = (viewWidth > viewHeight) doublePage = (viewWidth > viewHeight)
&& ReadBook.pageAnim() != 3 && ReadBook.pageAnim() != 3
} }
} }

@ -299,7 +299,7 @@ class BookSourceEditActivity :
reviewEntities.clear() reviewEntities.clear()
reviewEntities.apply { reviewEntities.apply {
add(EditEntity("reviewUrl", rr?.reviewUrl, R.string.rule_review_url)) add(EditEntity("reviewUrl", rr?.reviewUrl, R.string.rule_review_url))
add(EditEntity("avatarRule", rr?.reviewUrl, R.string.rule_avatar)) add(EditEntity("avatarRule", rr?.avatarRule, R.string.rule_avatar))
add(EditEntity("contentRule", rr?.contentRule, R.string.rule_review_content)) add(EditEntity("contentRule", rr?.contentRule, R.string.rule_review_content))
add(EditEntity("postTimeRule", rr?.postTimeRule, R.string.rule_post_time)) add(EditEntity("postTimeRule", rr?.postTimeRule, R.string.rule_post_time))
add(EditEntity("reviewQuoteUrl", rr?.reviewQuoteUrl, R.string.rule_review_quote)) add(EditEntity("reviewQuoteUrl", rr?.reviewQuoteUrl, R.string.rule_review_quote))

@ -84,6 +84,13 @@
android:checked="false" android:checked="false"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/menu_enable_review"
android:title="@string/review"
android:checkable="true"
android:checked="false"
app:showAsAction="never" />
<item <item
android:id="@+id/menu_image_style" android:id="@+id/menu_image_style"
android:title="@string/image_style" android:title="@string/image_style"

Loading…
Cancel
Save