This commit is contained in:
Horis 2024-02-08 23:01:19 +08:00
parent 4537f1325a
commit 1111e36c41
8 changed files with 207 additions and 43 deletions

View File

@ -537,20 +537,33 @@ object ReadBookConfig {
var footerMode: Int = 0
) {
private var textColorIntEInk = Color.parseColor(textColorEInk)
private var textColorIntNight = Color.parseColor(textColorNight)
private var textColorInt = Color.parseColor(textColor)
fun setCurTextColor(color: Int) {
when {
AppConfig.isEInkMode -> textColorEInk = "#${color.hexString}"
AppConfig.isNightTheme -> textColorNight = "#${color.hexString}"
else -> textColor = "#${color.hexString}"
AppConfig.isEInkMode -> {
textColorEInk = "#${color.hexString}"
textColorIntEInk = color
}
AppConfig.isNightTheme -> {
textColorNight = "#${color.hexString}"
textColorIntNight = color
}
else -> {
textColor = "#${color.hexString}"
textColorInt = color
}
}
ChapterProvider.upStyle()
}
fun curTextColor(): Int {
return when {
AppConfig.isEInkMode -> Color.parseColor(textColorEInk)
AppConfig.isNightTheme -> Color.parseColor(textColorNight)
else -> Color.parseColor(textColor)
AppConfig.isEInkMode -> textColorIntEInk
AppConfig.isNightTheme -> textColorIntNight
else -> textColorInt
}
}

View File

@ -15,13 +15,11 @@ import io.legado.app.help.coroutine.Coroutine
import io.legado.app.model.webBook.WebBook
import io.legado.app.service.CacheBookService
import io.legado.app.utils.postEvent
import io.legado.app.utils.startService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.delay
import java.util.concurrent.ConcurrentHashMap
import kotlin.coroutines.CoroutineContext

View File

@ -3,11 +3,15 @@ package io.legado.app.ui.book.read.page
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Picture
import android.graphics.RectF
import android.os.Build
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import androidx.core.graphics.record
import io.legado.app.R
import io.legado.app.constant.PageAnim
import io.legado.app.constant.PreferKey
import io.legado.app.data.entities.Bookmark
import io.legado.app.help.book.isImage
@ -61,6 +65,10 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
//滚动参数
private val pageFactory: TextPageFactory get() = callBack.pageFactory
private var pageOffset = 0
private lateinit var picture: Picture
private var pictureIsDirty = true
private val atLeastApi23 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
private val isNoAnim get() = ReadBook.pageAnim() == PageAnim.noAnim
//绘制图片的paint
private val imagePaint by lazy {
@ -71,6 +79,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
init {
callBack = activity as CallBack
if (atLeastApi23) {
picture = Picture()
}
}
/**
@ -108,7 +119,17 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
canvas.translate(0f, scrollY.toFloat())
}
canvas.clipRect(visibleRect)
drawPage(canvas)
if (atLeastApi23 && !callBack.isScroll && !isNoAnim) {
if (pictureIsDirty) {
pictureIsDirty = false
picture.record(width, height) {
drawPage(this)
}
}
canvas.drawPicture(picture)
} else {
drawPage(canvas)
}
}
/**
@ -288,6 +309,15 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
invalidate()
}
override fun invalidate() {
super.invalidate()
invalidatePicture()
}
private fun invalidatePicture() {
pictureIsDirty = true
}
/**
* 重置滚动位置
*/

View File

@ -104,7 +104,6 @@ class ReadView(context: Context, attrs: AttributeSet) :
addView(nextPage)
addView(curPage)
addView(prevPage)
nextPage.invisible()
prevPage.invisible()
curPage.markAsMainView()
if (!isInEditMode) {
@ -516,6 +515,12 @@ class ReadView(context: Context, attrs: AttributeSet) :
}
}
(pageDelegate as? ScrollPageDelegate)?.noAnim = AppConfig.noAnimScrollPage
pageDelegate?.setViewSize(width, height)
if (pageDelegate is NoAnimPageDelegate) {
nextPage.invisible()
} else {
nextPage.visible()
}
}
/**

View File

@ -2,7 +2,11 @@ package io.legado.app.ui.book.read.page.delegate
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Picture
import android.graphics.drawable.GradientDrawable
import android.os.Build
import androidx.core.graphics.withClip
import androidx.core.graphics.withTranslation
import io.legado.app.ui.book.read.page.ReadView
import io.legado.app.ui.book.read.page.entities.PageDirection
import io.legado.app.utils.screenshot
@ -11,12 +15,23 @@ class CoverPageDelegate(readView: ReadView) : HorizontalPageDelegate(readView) {
private val bitmapMatrix = Matrix()
private val shadowDrawableR: GradientDrawable
private lateinit var curPicture: Picture
private lateinit var prevPicture: Picture
private lateinit var nextPicture: Picture
private val atLeastApi23 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
init {
val shadowColors = intArrayOf(0x66111111, 0x00000000)
shadowDrawableR = GradientDrawable(
GradientDrawable.Orientation.LEFT_RIGHT, shadowColors
)
shadowDrawableR.gradientType = GradientDrawable.LINEAR_GRADIENT
if (atLeastApi23) {
curPicture = Picture()
prevPicture = Picture()
nextPicture = Picture()
}
}
override fun onDraw(canvas: Canvas) {
@ -32,52 +47,84 @@ class CoverPageDelegate(readView: ReadView) : HorizontalPageDelegate(readView) {
val distanceX = if (offsetX > 0) offsetX - viewWidth else offsetX + viewWidth
if (mDirection == PageDirection.PREV) {
if (offsetX <= viewWidth) {
bitmapMatrix.setTranslate(distanceX, 0.toFloat())
prevBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
addShadow(distanceX.toInt(), canvas)
if (!atLeastApi23) {
bitmapMatrix.setTranslate(distanceX, 0.toFloat())
prevBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
} else {
canvas.withTranslation(distanceX) {
drawPicture(prevPicture)
}
}
addShadow(distanceX, canvas)
} else {
prevBitmap?.let { canvas.drawBitmap(it, 0f, 0f, null) }
}
} else if (mDirection == PageDirection.NEXT) {
bitmapMatrix.setTranslate(distanceX - viewWidth, 0.toFloat())
nextBitmap?.let {
canvas.apply {
save()
val width = it.width.toFloat()
val height = it.height.toFloat()
clipRect(width + offsetX, 0f, width, height)
drawBitmap(it, 0f, 0f, null)
restore()
if (!atLeastApi23) {
prevBitmap?.let { canvas.drawBitmap(it, 0f, 0f, null) }
} else {
canvas.drawPicture(prevPicture)
}
}
curBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
addShadow(distanceX.toInt(), canvas)
} else if (mDirection == PageDirection.NEXT) {
if (!atLeastApi23) {
bitmapMatrix.setTranslate(distanceX - viewWidth, 0.toFloat())
nextBitmap?.let {
val width = it.width.toFloat()
val height = it.height.toFloat()
canvas.withClip(width + offsetX, 0f, width, height) {
drawBitmap(it, 0f, 0f, null)
}
}
curBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
} else {
val width = nextPicture.width.toFloat()
val height = nextPicture.height.toFloat()
canvas.withClip(width + offsetX, 0f, width, height) {
drawPicture(nextPicture)
}
canvas.withTranslation(distanceX - viewWidth) {
drawPicture(curPicture)
}
}
addShadow(distanceX, canvas)
}
}
override fun setBitmap() {
when (mDirection) {
PageDirection.PREV -> {
PageDirection.PREV -> if (!atLeastApi23) {
prevBitmap = prevPage.screenshot(prevBitmap, canvas)
} else {
prevPage.screenshot(prevPicture)
}
PageDirection.NEXT -> {
PageDirection.NEXT -> if (!atLeastApi23) {
nextBitmap = nextPage.screenshot(nextBitmap, canvas)
curBitmap = curPage.screenshot(curBitmap, canvas)
} else {
nextPage.screenshot(nextPicture)
curPage.screenshot(curPicture)
}
else -> Unit
}
}
private fun addShadow(left: Int, canvas: Canvas) {
if (left < 0) {
shadowDrawableR.setBounds(left + viewWidth, 0, left + viewWidth + 30, viewHeight)
shadowDrawableR.draw(canvas)
} else if (left > 0) {
shadowDrawableR.setBounds(left, 0, left + 30, viewHeight)
private fun addShadow(left: Float, canvas: Canvas) {
if (left == 0f) return
val dx = if (left < 0) {
left + viewWidth
} else {
left
}
canvas.withTranslation(dx) {
shadowDrawableR.draw(canvas)
}
}
override fun setViewSize(width: Int, height: Int) {
super.setViewSize(width, height)
shadowDrawableR.setBounds(0, 0, 30, viewHeight)
}
override fun onAnimStop() {
if (!isCancel) {
readView.fillPage(mDirection)
@ -97,6 +144,7 @@ class CoverPageDelegate(readView: ReadView) : HorizontalPageDelegate(readView) {
} else {
-(touchX + (viewWidth - startX))
}
else -> distanceX =
if (isCancel) {
-(touchX - startX)

View File

@ -90,6 +90,7 @@ abstract class PageDelegate(protected val readView: ReadView) {
}
}
@CallSuper
open fun setViewSize(width: Int, height: Int) {
viewWidth = width
viewHeight = height

View File

@ -2,13 +2,50 @@ package io.legado.app.ui.book.read.page.delegate
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Picture
import android.os.Build
import androidx.core.graphics.withTranslation
import io.legado.app.ui.book.read.page.ReadView
import io.legado.app.ui.book.read.page.entities.PageDirection
import io.legado.app.utils.screenshot
class SlidePageDelegate(readView: ReadView) : HorizontalPageDelegate(readView) {
private val bitmapMatrix = Matrix()
private lateinit var curPicture: Picture
private lateinit var prevPicture: Picture
private lateinit var nextPicture: Picture
private val atLeastApi23 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
init {
if (atLeastApi23) {
curPicture = Picture()
prevPicture = Picture()
nextPicture = Picture()
}
}
override fun setBitmap() {
if (!atLeastApi23) {
return super.setBitmap()
}
when (mDirection) {
PageDirection.PREV -> {
prevPage.screenshot(prevPicture)
curPage.screenshot(curPicture)
}
PageDirection.NEXT -> {
nextPage.screenshot(nextPicture)
curPage.screenshot(curPicture)
}
else -> Unit
}
}
override fun onAnimStart(animationSpeed: Int) {
val distanceX: Float
when (mDirection) {
@ -22,6 +59,7 @@ class SlidePageDelegate(readView: ReadView) : HorizontalPageDelegate(readView) {
} else {
-(touchX + (viewWidth - startX))
}
else -> distanceX =
if (isCancel) {
-(touchX - startX)
@ -41,15 +79,33 @@ class SlidePageDelegate(readView: ReadView) : HorizontalPageDelegate(readView) {
val distanceX = if (offsetX > 0) offsetX - viewWidth else offsetX + viewWidth
if (!isRunning) return
if (mDirection == PageDirection.PREV) {
bitmapMatrix.setTranslate(distanceX + viewWidth, 0.toFloat())
curBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
bitmapMatrix.setTranslate(distanceX, 0.toFloat())
prevBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
if (!atLeastApi23) {
bitmapMatrix.setTranslate(distanceX + viewWidth, 0.toFloat())
curBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
bitmapMatrix.setTranslate(distanceX, 0.toFloat())
prevBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
} else {
canvas.withTranslation(distanceX + viewWidth) {
drawPicture(curPicture)
}
canvas.withTranslation(distanceX) {
drawPicture(prevPicture)
}
}
} else if (mDirection == PageDirection.NEXT) {
bitmapMatrix.setTranslate(distanceX, 0.toFloat())
nextBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
bitmapMatrix.setTranslate(distanceX - viewWidth, 0.toFloat())
curBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
if (!atLeastApi23) {
bitmapMatrix.setTranslate(distanceX, 0.toFloat())
nextBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
bitmapMatrix.setTranslate(distanceX - viewWidth, 0.toFloat())
curBitmap?.let { canvas.drawBitmap(it, bitmapMatrix, null) }
} else {
canvas.withTranslation(distanceX) {
drawPicture(nextPicture)
}
canvas.withTranslation(distanceX - viewWidth) {
drawPicture(curPicture)
}
}
}
}

View File

@ -7,6 +7,7 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Picture
import android.os.Build
import android.text.Html
import android.view.MotionEvent
@ -25,6 +26,8 @@ import androidx.annotation.ColorInt
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.menu.MenuPopupHelper
import androidx.appcompat.widget.PopupMenu
import androidx.core.graphics.record
import androidx.core.graphics.withTranslation
import androidx.core.view.get
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.ViewPager
@ -163,6 +166,16 @@ fun View.screenshot(bitmap: Bitmap? = null, canvas: Canvas? = null): Bitmap? {
}
}
fun View.screenshot(picture: Picture) {
if (width > 0 && height > 0) {
picture.record(width, height) {
withTranslation(-scrollX.toFloat(), -scrollY.toFloat()) {
draw(this)
}
}
}
}
fun View.setPaddingBottom(bottom: Int) {
setPadding(paddingLeft, paddingTop, paddingRight, bottom)
}