diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt index 07c984c69..fb2c27629 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -97,6 +97,7 @@ object PreferKey { const val preDownloadNum = "preDownloadNum" const val mangaPreDownloadNum = "mangaPreDownloadNum" const val mangaAutoPageSpeed = "mangaAutoPageSpeed" + const val mangaFooterConfig = "mangaFooterConfig" const val singlePageScrolling = "singlePageScrolling" const val disableClickScroller = "disableClickScroller" const val autoRefresh = "auto_refresh" diff --git a/app/src/main/java/io/legado/app/help/config/AppConfig.kt b/app/src/main/java/io/legado/app/help/config/AppConfig.kt index 7b557e622..e7fabaf61 100644 --- a/app/src/main/java/io/legado/app/help/config/AppConfig.kt +++ b/app/src/main/java/io/legado/app/help/config/AppConfig.kt @@ -643,5 +643,13 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener { set(value) { appCtx.putPrefInt(PreferKey.mangaAutoPageSpeed, value) } + + //漫画页脚配置 + var mangaFooterConfig + get() = appCtx.getPrefString(PreferKey.mangaFooterConfig, "") + set(value) { + appCtx.putPrefString(PreferKey.mangaFooterConfig, value) + } + } diff --git a/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaActivity.kt b/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaActivity.kt index 9f2e19a1c..54b3cbcc3 100644 --- a/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/manga/ReadMangaActivity.kt @@ -26,6 +26,7 @@ import com.bumptech.glide.util.FixedPreloadSizeProvider import io.legado.app.BuildConfig import io.legado.app.R import io.legado.app.base.VMBaseActivity +import io.legado.app.constant.EventBus import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookProgress @@ -43,16 +44,22 @@ import io.legado.app.model.recyclerView.ReaderLoading import io.legado.app.receiver.NetworkChangedListener import io.legado.app.ui.book.changesource.ChangeBookSourceDialog import io.legado.app.ui.book.info.BookInfoActivity +import io.legado.app.ui.book.manga.config.MangaFooterConfig +import io.legado.app.ui.book.manga.config.MangaFooterSettingDialog import io.legado.app.ui.book.manga.rv.MangaAdapter import io.legado.app.ui.book.read.MangaMenu import io.legado.app.ui.book.read.ReadBookActivity.Companion.RESULT_DELETED import io.legado.app.ui.book.toc.TocActivityResult +import io.legado.app.ui.widget.ReaderInfoBarView import io.legado.app.ui.widget.number.NumberPickerDialog import io.legado.app.ui.widget.recycler.LoadMoreView +import io.legado.app.utils.GSON import io.legado.app.utils.NetworkUtils import io.legado.app.utils.StartActivityContract +import io.legado.app.utils.fromJsonObject import io.legado.app.utils.getCompatColor import io.legado.app.utils.gone +import io.legado.app.utils.observeEvent import io.legado.app.utils.printOnDebug import io.legado.app.utils.showDialogFragment import io.legado.app.utils.toastOnUi @@ -101,6 +108,8 @@ class ReadMangaActivity : VMBaseActivity() } private var mMangaAutoPageSpeed = mInitMangaAutoPageSpeed + private var mMangaFooterConfig: MangaFooterConfig? = null + private val mLabelBuilder by lazy { StringBuilder() } private val autoScrollHandler = Handler(Looper.getMainLooper()) private val autoScrollRunnable = object : Runnable { @@ -170,6 +179,18 @@ class ReadMangaActivity : VMBaseActivity() } } loadMoreView.gone() + mMangaFooterConfig = GSON.fromJsonObject(AppConfig.mangaFooterConfig).getOrNull() + ?: MangaFooterConfig() + observeEvent(EventBus.UP_CONFIG) { + mMangaFooterConfig = it + AppConfig.mangaFooterConfig = GSON.toJson(it) + upInfoBar( + ReadManga.durChapterPagePos.plus(1), + ReadManga.durChapterPageCount, + ReadManga.durChapterPos.plus(1), + ReadManga.durChapterCount + ) + } } private fun initRecyclerView() { @@ -291,12 +312,37 @@ class ReadMangaActivity : VMBaseActivity() private fun upInfoBar( chapterPagePos: Int, chapterPageCount: Int, chapterPos: Int, chapterCount: Int, ) { + mMangaFooterConfig?.run { + mLabelBuilder.clear() + binding.infobar.isGone = this.hideFooter + binding.infobar.textInfoAlignment =this.footerOrientation + if (!this.hidePageNumber) { + if (!this.hidePageNumberLabel) { + mLabelBuilder.append(getString(R.string.manga_check_page_number)) + } + mLabelBuilder.append("${chapterPos}/${chapterCount}").append(" ") + } + + if (!this.hideChapter) { + if (!this.hideChapterLabel) { + mLabelBuilder.append(getString(R.string.manga_check_chapter)) + } + mLabelBuilder.append("${chapterPagePos}/${chapterPageCount}").append(" ") + } + + if (!this.hideProgressRatio) { + if (!this.hideProgressRatioLabel) { + mLabelBuilder.append(getString(R.string.manga_check_progress)) + } + mLabelBuilder.append( + "${ + chapterPagePos.div(chapterPageCount).times(100) + }%" + ) + } + } binding.infobar.update( - chapterPagePos, - chapterPageCount, - chapterPagePos.times(1f).div(chapterPageCount.times(1f)), - chapterPos, - chapterCount + if (mLabelBuilder.isEmpty()) "" else mLabelBuilder.toString() ) } @@ -471,6 +517,10 @@ class ReadMangaActivity : VMBaseActivity() startAutoPage() } } + + R.id.menu_manga_footer_config -> { + MangaFooterSettingDialog().show(supportFragmentManager, "mangaFooterSettingDialog") + } } return super.onCompatOptionsItemSelected(item) } diff --git a/app/src/main/java/io/legado/app/ui/book/manga/config/MangaFooterConfig.kt b/app/src/main/java/io/legado/app/ui/book/manga/config/MangaFooterConfig.kt new file mode 100644 index 000000000..4a126e097 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/book/manga/config/MangaFooterConfig.kt @@ -0,0 +1,16 @@ +package io.legado.app.ui.book.manga.config + +import androidx.annotation.Keep +import io.legado.app.ui.widget.ReaderInfoBarView + +@Keep +data class MangaFooterConfig( + var hideChapterLabel: Boolean = false, + var hideChapter: Boolean = false, + var hidePageNumberLabel: Boolean = false, + var hidePageNumber: Boolean = false, + var hideProgressRatioLabel: Boolean = false, + var hideProgressRatio: Boolean = false, + var footerOrientation: Int = ReaderInfoBarView.ALIGN_LEFT,//默认靠左 + var hideFooter: Boolean = false +) \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/manga/config/MangaFooterSettingDialog.kt b/app/src/main/java/io/legado/app/ui/book/manga/config/MangaFooterSettingDialog.kt new file mode 100644 index 000000000..a3311f9b3 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/book/manga/config/MangaFooterSettingDialog.kt @@ -0,0 +1,101 @@ +package io.legado.app.ui.book.manga.config + +import android.os.Bundle +import android.view.View +import android.view.ViewGroup +import io.legado.app.R +import io.legado.app.base.BaseDialogFragment +import io.legado.app.constant.EventBus +import io.legado.app.databinding.DialogMangaFooterSettingBinding +import io.legado.app.help.config.AppConfig +import io.legado.app.ui.widget.ReaderInfoBarView +import io.legado.app.utils.GSON +import io.legado.app.utils.fromJsonObject +import io.legado.app.utils.postEvent +import io.legado.app.utils.setLayout +import io.legado.app.utils.viewbindingdelegate.viewBinding + +class MangaFooterSettingDialog : BaseDialogFragment(R.layout.dialog_manga_footer_setting) { + val config = GSON.fromJsonObject(AppConfig.mangaFooterConfig).getOrNull() + ?: MangaFooterConfig() + private val binding by viewBinding(DialogMangaFooterSettingBinding::bind) + + override fun onStart() { + super.onStart() + setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + } + + override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { + + binding.cbChapterLabel.run { + isChecked = config.hideChapterLabel + setOnCheckedChangeListener { _, isChecked -> + config.hideChapterLabel = isChecked + postEvent(EventBus.UP_CONFIG, config) + } + } + binding.cbChapter.run { + isChecked = config.hideChapter + setOnCheckedChangeListener { _, isChecked -> + config.hideChapter = isChecked + postEvent(EventBus.UP_CONFIG, config) + } + } + binding.cbPageNumberLabel.run { + isChecked = config.hidePageNumberLabel + setOnCheckedChangeListener { _, isChecked -> + config.hidePageNumberLabel = isChecked + postEvent(EventBus.UP_CONFIG, config) + } + } + binding.cbPageNumber.run { + isChecked = config.hidePageNumber + setOnCheckedChangeListener { _, isChecked -> + config.hidePageNumber = isChecked + postEvent(EventBus.UP_CONFIG, config) + } + } + binding.cbProgressRatioLabel.run { + isChecked = config.hideProgressRatioLabel + setOnCheckedChangeListener { _, isChecked -> + config.hideProgressRatioLabel = isChecked + postEvent(EventBus.UP_CONFIG, config) + } + } + binding.cbProgressRatio.run { + isChecked = config.hideProgressRatio + setOnCheckedChangeListener { _, isChecked -> + config.hideProgressRatio = isChecked + postEvent(EventBus.UP_CONFIG, config) + } + } + binding.rgFooterOrientation.check(if (config.footerOrientation == ReaderInfoBarView.ALIGN_CENTER) R.id.rbCenter else R.id.rbLeft) + binding.rgFooterOrientation.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.rbLeft -> { + config.footerOrientation = ReaderInfoBarView.ALIGN_LEFT + } + + R.id.rbCenter -> { + config.footerOrientation = ReaderInfoBarView.ALIGN_CENTER + } + } + postEvent(EventBus.UP_CONFIG, config) + } + + binding.rgFooter.check(if (config.hideFooter) R.id.rbDisable else R.id.rbEnable) + binding.rgFooter.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.rbEnable -> { + config.hideFooter = false + } + + R.id.rbDisable -> { + config.hideFooter = true + } + } + postEvent(EventBus.UP_CONFIG, config) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/widget/ReaderInfoBarView.kt b/app/src/main/java/io/legado/app/ui/widget/ReaderInfoBarView.kt index 37df004dc..d9425b095 100644 --- a/app/src/main/java/io/legado/app/ui/widget/ReaderInfoBarView.kt +++ b/app/src/main/java/io/legado/app/ui/widget/ReaderInfoBarView.kt @@ -24,6 +24,7 @@ import java.text.NumberFormat import java.text.SimpleDateFormat import java.util.Date import java.util.Locale +import kotlin.math.min import com.google.android.material.R as materialR class ReaderInfoBarView @JvmOverloads constructor( @@ -32,6 +33,11 @@ class ReaderInfoBarView @JvmOverloads constructor( @AttrRes defStyleAttr: Int = 0, ) : View(context, attrs, defStyleAttr) { + companion object { + const val ALIGN_LEFT = 0 + const val ALIGN_CENTER = 1 + } + private val paint = Paint(Paint.ANTI_ALIAS_FLAG) private val textBounds = Rect() private val timeFormat = SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT) @@ -54,12 +60,16 @@ class ReaderInfoBarView @JvmOverloads constructor( 200, ) + var textInfoAlignment: Int = ALIGN_CENTER + set(value) { + field = value + updateTextSize() + invalidate() + } private var timeText = timeFormat.format(Date()) private var text: String = "" - private val innerHeight get() = height - paddingTop - paddingBottom - insetTop - private val innerWidth get() = width - paddingLeft - paddingRight - insetLeft - insetRight @@ -76,12 +86,29 @@ class ReaderInfoBarView @JvmOverloads constructor( override fun onDraw(canvas: Canvas) { super.onDraw(canvas) val ty = innerHeight / 2f + textBounds.height() / 2f - textBounds.bottom - paint.textAlign = Paint.Align.LEFT + + val textX = when (textInfoAlignment) { + ALIGN_CENTER -> { + val textWidth = paint.measureText(text) + (width / 2f).coerceIn( + paddingLeft + insetLeft + cutoutInsetLeft + textWidth / 2, + width - paddingRight - insetRight - cutoutInsetRight - textWidth / 2 + ) + } + + else -> (paddingLeft + insetLeft + cutoutInsetLeft).toFloat() + } + paint.textAlign = when (textInfoAlignment) { + ALIGN_CENTER -> Paint.Align.CENTER + else -> Paint.Align.LEFT + } + canvas.drawTextOutline( text, - (paddingLeft + insetLeft + cutoutInsetLeft).toFloat(), + textX, paddingTop + insetTop + ty, ) + paint.textAlign = Paint.Align.RIGHT canvas.drawTextOutline( timeText, @@ -117,21 +144,8 @@ class ReaderInfoBarView @JvmOverloads constructor( context.unregisterReceiver(timeReceiver) } - fun update( - currentPage: Int, - totalPage: Int, - percent: Float, - chapterIndex: Int, - chapterCount: Int - ) { - text = context.getString( - R.string.book_reader_info_bar, - chapterIndex, - chapterCount, - currentPage, - totalPage, - if (percent in 0f..1f) (percent * 100).format() else "" - ) + fun update(label: String) { + text = label updateTextSize() invalidate() } @@ -164,12 +178,30 @@ class ReaderInfoBarView @JvmOverloads constructor( private fun updateTextSize() { - val str = text + timeText val testTextSize = 48f paint.textSize = testTextSize - paint.getTextBounds(str, 0, str.length, textBounds) - paint.textSize = testTextSize * innerHeight / textBounds.height() - paint.getTextBounds(str, 0, str.length, textBounds) + paint.getTextBounds(text, 0, text.length, textBounds) + + val maxTextHeight = innerHeight * 0.8f + val scaleFactor = min( + maxTextHeight / textBounds.height(), + calculateMaxWidthScale() + ) + paint.textSize = testTextSize * scaleFactor + + paint.getTextBounds(text, 0, text.length, textBounds) + } + + private fun calculateMaxWidthScale(): Float { + return when (textInfoAlignment) { + ALIGN_CENTER -> { + val availableWidth = innerWidth - cutoutInsetLeft - cutoutInsetRight + val requiredWidth = paint.measureText(text) + if (requiredWidth > availableWidth) availableWidth / requiredWidth else 1f + } + + else -> 1f + } } private fun Canvas.drawTextOutline(text: String, x: Float, y: Float) { diff --git a/app/src/main/res/layout/dialog_manga_footer_setting.xml b/app/src/main/res/layout/dialog_manga_footer_setting.xml new file mode 100644 index 000000000..77c9e7112 --- /dev/null +++ b/app/src/main/res/layout/dialog_manga_footer_setting.xml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/book_manga.xml b/app/src/main/res/menu/book_manga.xml index e59962f9d..931648016 100644 --- a/app/src/main/res/menu/book_manga.xml +++ b/app/src/main/res/menu/book_manga.xml @@ -57,4 +57,9 @@ android:visible="false" android:title="@string/manga_auto_page_speed" app:showAsAction="never" /> + + diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index aff6e7956..43ec94ad2 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -1187,8 +1187,23 @@ 禁用点击翻页 开启自动翻页 翻页速度 %s 秒 + 页脚配置 设置自动翻页速度 页数. %1$d/%2$d 章节. %3$d/%4$d -> %5$s%% Descargar el siguiente capítulo Descargar todos los capítulos + 《章节和文案》隐藏 + 《章节.》文案 + 章节 + 《页数和文案》隐藏 + 《页数.》文案 + 页数 + 《总进度和文案》隐藏 + 《总进度.》文案 + 总进度 + 页脚 + 靠左 + 居中 + 禁用 + 启用 diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 9bf7dc048..3e3471cde 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -1190,8 +1190,23 @@ 禁用点击翻页 开启自动翻页 翻页速度 %s 秒 + 页脚配置 设置自动翻页速度 页数. %1$d/%2$d 章节. %3$d/%4$d -> %5$s%% 下载之后章节 下载全部章节 + 《章节和文案》隐藏 + 《章节.》文案 + 章节 + 《页数和文案》隐藏 + 《页数.》文案 + 页数 + 《总进度和文案》隐藏 + 《总进度.》文案 + 总进度 + 页脚 + 靠左 + 居中 + 禁用 + 启用 diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 0fceeadbe..dfa20b753 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -1190,8 +1190,23 @@ 禁用点击翻页 开启自动翻页 翻页速度 %s 秒 + 页脚配置 设置自动翻页速度 页数. %1$d/%2$d 章节. %3$d/%4$d -> %5$s%% Faça o download do próximo capítulo Download de todos os capítulos + 《章节和文案》隐藏 + 《章节.》文案 + 章节 + 《页数和文案》隐藏 + 《页数.》文案 + 页数 + 《总进度和文案》隐藏 + 《总进度.》文案 + 总进度 + 页脚 + 靠左 + 居中 + 禁用 + 启用 diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 02fa306d8..345218f90 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -1186,8 +1186,23 @@ Còn 禁用点击翻页 开启自动翻页 翻页速度 %s 秒 + 页脚配置 设置自动翻页速度 页数. %1$d/%2$d 章节. %3$d/%4$d -> %5$s%% Tải xuống chương tiếp theo Tải xuống tất cả các chương + 《章节和文案》隐藏 + 《章节.》文案 + 章节 + 《页数和文案》隐藏 + 《页数.》文案 + 页数 + 《总进度和文案》隐藏 + 《总进度.》文案 + 总进度 + 页脚 + 靠左 + 居中 + 禁用 + 启用 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 414bd4fff..beb2dc009 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -1187,8 +1187,23 @@ 禁用点击翻页 开启自动翻页 翻页速度 %s 秒 + 页脚配置 设置自动翻页速度 页数. %1$d/%2$d 章节. %3$d/%4$d -> %5$s%% 下載之後章節 下載全部章節 + 《章节和文案》隐藏 + 《章节.》文案 + 章节 + 《页数和文案》隐藏 + 《页数.》文案 + 页数 + 《总进度和文案》隐藏 + 《总进度.》文案 + 总进度 + 页脚 + 靠左 + 居中 + 禁用 + 启用 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index d37101bbe..5c9d29138 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1189,8 +1189,23 @@ 禁用点击翻页 开启自动翻页 翻页速度 %s 秒 + 页脚配置 设置自动翻页速度 页数. %1$d/%2$d 章节. %3$d/%4$d -> %5$s%% 下載之後章節 下載全部章節 + 《章节和文案》隐藏 + 《章节.》文案 + 章节 + 《页数和文案》隐藏 + 《页数.》文案 + 页数 + 《总进度和文案》隐藏 + 《总进度.》文案 + 总进度 + 页脚 + 靠左 + 居中 + 禁用 + 启用 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 37e3ab3d6..d787b9342 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -1189,8 +1189,23 @@ 禁用点击翻页 开启自动翻页 翻页速度 %s 秒 + 页脚配置 设置自动翻页速度 页数. %1$d/%2$d 章节. %3$d/%4$d -> %5$s%% 下载之后章节 下载全部章节 + 《章节和文案》隐藏 + 《章节.》文案 + 章节 + 《页数和文案》隐藏 + 《页数.》文案 + 页数 + 《总进度和文案》隐藏 + 《总进度.》文案 + 总进度 + 页脚 + 靠左 + 居中 + 禁用 + 启用 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1ac4ed73d..dc1ef3380 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1190,8 +1190,23 @@ 禁用点击翻页 开启自动翻页 翻页速度 %s 秒 + 页脚配置 设置自动翻页速度 页数. %1$d/%2$d 章节. %3$d/%4$d -> %5$s%% Download the chapter after Download all chapter + 《章节和文案》隐藏 + 《章节.》文案 + 章节 + 《页数和文案》隐藏 + 《页数.》文案 + 页数 + 《总进度和文案》隐藏 + 《总进度.》文案 + 总进度 + 页脚 + 靠左 + 居中 + 禁用 + 启用