diff --git a/app/src/main/java/io/legado/app/help/config/ReadTipConfig.kt b/app/src/main/java/io/legado/app/help/config/ReadTipConfig.kt index dc36ffae0..068b99282 100644 --- a/app/src/main/java/io/legado/app/help/config/ReadTipConfig.kt +++ b/app/src/main/java/io/legado/app/help/config/ReadTipConfig.kt @@ -19,9 +19,12 @@ object ReadTipConfig { const val timeBattery = 8 const val timeBatteryPercentage = 9 const val totalProgress1 = 11 + const val chapterTitleArrow = 12 + const val batteryInside = 13 + const val batteryIcon = 14 val tipValues = arrayOf( - none, bookName, chapterTitle, time, battery, batteryPercentage, page, + none, bookName, chapterTitle, chapterTitleArrow, time, battery, batteryInside, batteryIcon, batteryPercentage, page, totalProgress, totalProgress1, pageAndTotal, timeBattery, timeBatteryPercentage ) val tipNames get() = appCtx.resources.getStringArray(R.array.read_tip).toList() diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt index 078c93ee8..f4432c6cc 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt @@ -31,7 +31,6 @@ import io.legado.app.utils.applyStatusBarPadding import io.legado.app.utils.dpToPx import io.legado.app.utils.gone import io.legado.app.utils.setOnApplyWindowInsetsListenerCompat -import io.legado.app.utils.setTextIfNotEqual import io.legado.app.utils.statusBarHeight import splitties.views.backgroundColor import java.util.Date @@ -55,6 +54,9 @@ class PageView(context: Context) : FrameLayout(context) { private var tvBookName: BatteryView? = null private var tvTimeBattery: BatteryView? = null private var tvTimeBatteryP: BatteryView? = null + private var tvTitleArrow: BatteryView? = null + private var tvBatteryInside: BatteryView? = null + private var tvBatteryIcon: BatteryView? = null private var isMainView = false var isScroll = false @@ -183,6 +185,13 @@ class PageView(context: Context) : FrameLayout(context) { typeface = ChapterProvider.typeface textSize = 12f } + tvTitleArrow = getTipView(ReadTipConfig.chapterTitleArrow)?.apply { + tag = ReadTipConfig.chapterTitleArrow + isBattery = false + typeface = ChapterProvider.typeface + textSize = 12f + batteryMode = BatteryView.BatteryMode.ARROW + } tvTime = getTipView(ReadTipConfig.time)?.apply { tag = ReadTipConfig.time isBattery = false @@ -193,6 +202,19 @@ class PageView(context: Context) : FrameLayout(context) { tag = ReadTipConfig.battery isBattery = true textSize = 11f + batteryMode = BatteryView.BatteryMode.OUTER + } + tvBatteryInside = getTipView(ReadTipConfig.batteryInside)?.apply { + tag = ReadTipConfig.batteryInside + isBattery = true + textSize = 11f + batteryMode = BatteryView.BatteryMode.INNER + } + tvBatteryIcon = getTipView(ReadTipConfig.batteryIcon)?.apply { + tag = ReadTipConfig.batteryIcon + isBattery = true + textSize = 11f + batteryMode = BatteryView.BatteryMode.ICON } tvPage = getTipView(ReadTipConfig.page)?.apply { tag = ReadTipConfig.page @@ -296,6 +318,8 @@ class PageView(context: Context) : FrameLayout(context) { fun upBattery(battery: Int) { this.battery = battery tvBattery?.setBattery(battery) + tvBatteryInside?.setBattery(battery) + tvBatteryIcon?.setBattery(battery) tvBatteryP?.text = "$battery%" upTimeBattery() } @@ -307,6 +331,8 @@ class PageView(context: Context) : FrameLayout(context) { private fun upTimeBattery() { val time = timeFormat.format(Date(System.currentTimeMillis())) tvTimeBattery?.setBattery(battery, time) + tvTimeBatteryP?.setBattery(battery, time) + tvTimeBattery?.text = "$time $battery%" tvTimeBatteryP?.text = "$time $battery%" } @@ -352,6 +378,7 @@ class PageView(context: Context) : FrameLayout(context) { fun setProgress(textPage: TextPage) = textPage.apply { tvBookName?.setTextIfNotEqual(ReadBook.book?.name) tvTitle?.setTextIfNotEqual(textPage.title) + tvTitleArrow?.setTextIfNotEqual(textPage.title) val readProgress = readProgress tvTotalProgress?.setTextIfNotEqual(readProgress) tvTotalProgress1?.setTextIfNotEqual("${chapterIndex.plus(1)}/${chapterSize}") diff --git a/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt b/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt index 1ff8f6fa3..9def47610 100644 --- a/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt +++ b/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt @@ -1,122 +1,140 @@ package io.legado.app.ui.widget -import android.annotation.SuppressLint import android.content.Context -import android.graphics.Canvas -import android.graphics.Paint -import android.graphics.Rect +import android.graphics.PorterDuff import android.graphics.Typeface -import android.os.Build -import android.text.StaticLayout import android.util.AttributeSet +import android.util.TypedValue +import android.view.LayoutInflater import androidx.annotation.ColorInt -import androidx.appcompat.widget.AppCompatTextView -import io.legado.app.help.config.AppConfig -import io.legado.app.utils.canvasrecorder.CanvasRecorderFactory -import io.legado.app.utils.canvasrecorder.recordIfNeededThenDraw +import androidx.constraintlayout.widget.ConstraintLayout +import io.legado.app.databinding.ViewBatteryBinding import io.legado.app.utils.dpToPx class BatteryView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null -) : AppCompatTextView(context, attrs) { +) : ConstraintLayout(context, attrs) { + + private val binding: ViewBatteryBinding = + ViewBatteryBinding.inflate(LayoutInflater.from(context), this, true) + + enum class BatteryMode { OUTER, INNER, ICON, ARROW } + private val batteryTypeface by lazy { Typeface.createFromAsset(context.assets, "font/number.ttf") } - private val batteryPaint = Paint() - private val outFrame = Rect() - private val polar = Rect() - private val canvasRecorder = CanvasRecorderFactory.create() - var isBattery = false - set(value) { - field = value - if (value && !isInEditMode) { - super.setTypeface(batteryTypeface) - postInvalidate() - } - } + private var battery: Int = 0 init { setPadding(4.dpToPx(), 3.dpToPx(), 6.dpToPx(), 3.dpToPx()) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - isFallbackLineSpacing = false - } - batteryPaint.strokeWidth = 1f.dpToPx() - batteryPaint.isAntiAlias = true - batteryPaint.color = paint.color + binding.batteryText.typeface = batteryTypeface + binding.batteryTextInner.typeface = batteryTypeface } - override fun setTypeface(tf: Typeface?) { - if (!isBattery) { - super.setTypeface(tf) + var isBattery = false + set(value) { + field = value + binding.arrowIcon.visibility = if (value) VISIBLE else GONE + binding.batteryTextInner.visibility = if (value) VISIBLE else GONE + binding.batteryTextInner.typeface = if (value) Typeface.DEFAULT else batteryTypeface + binding.batteryText.typeface = if (value) Typeface.DEFAULT else batteryTypeface + binding.batteryIcon.visibility = if (value) VISIBLE else GONE + binding.batteryFill.visibility = if (value) VISIBLE else GONE } + + var text: CharSequence? + get() = binding.batteryText.text + set(value) { + binding.batteryText.text = value + binding.batteryTextInner.text = value + } + + var batteryMode: BatteryMode = BatteryMode.OUTER + set(value) { + field = value + updateMode() + } + + var typeface: Typeface? + get() = binding.batteryText.typeface + set(value) { + binding.batteryText.typeface = value ?: Typeface.DEFAULT + binding.batteryTextInner.typeface = value ?: Typeface.DEFAULT + } + + var textSize: Float + get() = binding.batteryText.textSize / binding.batteryText.resources.displayMetrics.density + set(value) { + binding.batteryText.setTextSize(TypedValue.COMPLEX_UNIT_SP, value) + } + + fun setTextColor(@ColorInt color: Int) { + binding.batteryText.setTextColor(color) + binding.batteryTextInner.setTextColor(color) + } + + fun setBattery(battery: Int, text: String? = null) { + this.battery = battery.coerceIn(0, 100) + binding.batteryText.text = text?.let { "$it $battery" } ?: battery.toString() + binding.batteryTextInner.text = text?.let { "$it $battery" } ?: battery.toString() + updateFill() } fun setColor(@ColorInt color: Int) { - setTextColor(color) - batteryPaint.color = color - invalidate() + binding.batteryText.setTextColor(color) + binding.batteryFill.setCardBackgroundColor(color) + binding.arrowIcon.setColorFilter(color, PorterDuff.Mode.SRC_IN) + binding.batteryIcon.setColorFilter(color, PorterDuff.Mode.SRC_IN) + binding.batteryIcon.alpha = 0.76f + binding.arrowIcon.alpha = 0.76f } - @SuppressLint("SetTextI18n") - fun setBattery(battery: Int, text: String? = null) { - this.battery = battery - if (text.isNullOrEmpty()) { - setText(battery.toString()) - } else { - setText("$text $battery") + fun setTextIfNotEqual(newText: String?) { + if (binding.batteryText.text?.toString() != newText) { + binding.batteryText.text = newText } } - override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { - super.onLayout(changed, left, top, right, bottom) - canvasRecorder.invalidate() - } - override fun onDraw(canvas: Canvas) { - if (AppConfig.optimizeRender) { - canvasRecorder.recordIfNeededThenDraw(canvas, width, height) { - super.onDraw(this) - drawBattery(this) + private fun updateMode() { + when (batteryMode) { + BatteryMode.OUTER -> { + binding.arrowIcon.visibility = GONE + binding.batteryText.visibility = VISIBLE + binding.batteryTextInner.visibility = GONE + binding.batteryFill.visibility = VISIBLE + } + BatteryMode.INNER -> { + binding.arrowIcon.visibility = GONE + binding.batteryText.visibility = GONE + binding.batteryTextInner.visibility = VISIBLE + binding.batteryFill.visibility = GONE + } + BatteryMode.ICON -> { + binding.arrowIcon.visibility = GONE + binding.batteryText.visibility = GONE + binding.batteryTextInner.visibility = GONE + binding.batteryFill.visibility = VISIBLE + } + BatteryMode.ARROW -> { + binding.batteryText.visibility = VISIBLE + binding.batteryTextInner.visibility = GONE + binding.batteryFill.visibility = GONE + binding.arrowIcon.visibility = VISIBLE } - } else { - super.onDraw(canvas) - drawBattery(canvas) } + updateFill() } - private fun drawBattery(canvas: Canvas) { - if (!isBattery) return - layout.getLineBounds(0, outFrame) - val batteryStart = layout - .getPrimaryHorizontal(text.length - battery.toString().length) - .toInt() + 2.dpToPx() - val batteryEnd = batteryStart + - StaticLayout.getDesiredWidth(battery.toString(), paint).toInt() + 4.dpToPx() - outFrame.set( - batteryStart, - 2.dpToPx(), - batteryEnd, - height - 2.dpToPx() - ) - val dj = (outFrame.bottom - outFrame.top) / 3 - polar.set( - batteryEnd, - outFrame.top + dj, - batteryEnd + 2.dpToPx(), - outFrame.bottom - dj - ) - batteryPaint.style = Paint.Style.STROKE - canvas.drawRect(outFrame, batteryPaint) - batteryPaint.style = Paint.Style.FILL - canvas.drawRect(polar, batteryPaint) - } - - @Suppress("UNNECESSARY_SAFE_CALL") - override fun invalidate() { - super.invalidate() - canvasRecorder?.invalidate() + private fun updateFill() { + post { + val maxWidth = 14.dpToPx() + val params = binding.batteryFill.layoutParams + params.width = (maxWidth * battery / 100f).toInt() + binding.batteryFill.layoutParams = params + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_battery.xml b/app/src/main/res/drawable/ic_battery.xml new file mode 100644 index 000000000..82b1a1e73 --- /dev/null +++ b/app/src/main/res/drawable/ic_battery.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/layout/view_battery.xml b/app/src/main/res/layout/view_battery.xml new file mode 100644 index 000000000..983cecc44 --- /dev/null +++ b/app/src/main/res/layout/view_battery.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rHK/arrays.xml b/app/src/main/res/values-zh-rHK/arrays.xml index 89c5005b1..d26dab26c 100644 --- a/app/src/main/res/values-zh-rHK/arrays.xml +++ b/app/src/main/res/values-zh-rHK/arrays.xml @@ -51,8 +51,11 @@ 書名 標題 + 標題+箭頭 時間 電量 + 電量內顯 + 僅電量圖標 電量% 頁數 進度(%) diff --git a/app/src/main/res/values-zh-rTW/arrays.xml b/app/src/main/res/values-zh-rTW/arrays.xml index 3daf623ae..b35aa7b63 100644 --- a/app/src/main/res/values-zh-rTW/arrays.xml +++ b/app/src/main/res/values-zh-rTW/arrays.xml @@ -88,8 +88,11 @@ 書名 標題 + 標題+箭頭 時間 電量 + 電量內顯 + 僅電量圖標 電量% 頁數 進度(%) diff --git a/app/src/main/res/values-zh/arrays.xml b/app/src/main/res/values-zh/arrays.xml index a16050365..6a9ce4b47 100644 --- a/app/src/main/res/values-zh/arrays.xml +++ b/app/src/main/res/values-zh/arrays.xml @@ -75,8 +75,11 @@ 书名 标题 + 带箭头的标题 时间 电量 + 电量内显 + 仅电量图标 电量% 页数 进度(%) diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index fa25c1488..e8661d7ee 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -142,8 +142,11 @@ Blank Book name Title + Title With Arrow Time Battery + Battery Inside + Battery Only Icon Battery% Pages Progress(%) diff --git a/app/version.properties b/app/version.properties index 63e5f0b45..ac3e62489 100644 --- a/app/version.properties +++ b/app/version.properties @@ -1,4 +1,4 @@ VERSION_MAJOR=3 VERSION_MINOR=26 VERSION_PATCH=2 -VERSION_SUFFIX=-beta.3 \ No newline at end of file +VERSION_SUFFIX=-beta.4 \ No newline at end of file