From cbdfbaffe1d6ffe6316988629645e34af251621f Mon Sep 17 00:00:00 2001 From: lhjgege <1079947827@qq.com> Date: Tue, 17 Jun 2025 20:52:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E6=BC=AB=E7=94=BB=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=A2=A8=E6=B0=B4=E5=B1=8F=E6=A8=A1=E5=BC=8F=20(#5181)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 新漫画增加墨水屏模式 * 增加水平滚动动画开关 * .... * .... * .... * .... * .... * .... --- .../java/io/legado/app/constant/PreferKey.kt | 5 +- .../io/legado/app/help/config/AppConfig.kt | 26 ++++++ .../java/io/legado/app/model/BookCover.kt | 18 ++++- .../app/ui/book/manga/ReadMangaActivity.kt | 57 ++++++++++++- .../ui/book/manga/config/MangaEpaperDialog.kt | 50 ++++++++++++ .../manga/entities/EpaperTransformation.kt | 80 +++++++++++++++++++ .../manga/entities/GrayscaleTransformation.kt | 57 +++++++++++++ .../book/manga/recyclerview/MangaAdapter.kt | 43 ++++++++-- .../app/ui/book/manga/recyclerview/MangaVH.kt | 5 +- .../res/layout/dialog_manga_color_filter.xml | 2 +- .../main/res/layout/dialog_manga_epaper.xml | 29 +++++++ app/src/main/res/menu/book_manga.xml | 28 +++++++ app/src/main/res/values-es-rES/strings.xml | 5 ++ app/src/main/res/values-ja-rJP/strings.xml | 5 ++ app/src/main/res/values-pt-rBR/strings.xml | 5 ++ app/src/main/res/values-vi/strings.xml | 5 ++ app/src/main/res/values-zh-rHK/strings.xml | 5 ++ app/src/main/res/values-zh-rTW/strings.xml | 4 + app/src/main/res/values-zh/strings.xml | 5 ++ app/src/main/res/values/strings.xml | 5 ++ 20 files changed, 424 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/io/legado/app/ui/book/manga/config/MangaEpaperDialog.kt create mode 100644 app/src/main/java/io/legado/app/ui/book/manga/entities/EpaperTransformation.kt create mode 100644 app/src/main/java/io/legado/app/ui/book/manga/entities/GrayscaleTransformation.kt create mode 100644 app/src/main/res/layout/dialog_manga_epaper.xml 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 4d68b998b..46ee4428c 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -102,6 +102,10 @@ object PreferKey { const val enableMangaHorizontalScroll = "enableMangaHorizontalScroll" const val hideMangaTitle = "hideMangaTitle" const val mangaColorFilter = "mangaColorFilter" + const val enableMangaEInk = "enableMangaEInk" + const val mangaEInkThreshold = "mangaEInkThreshold" + const val disableHorizontalAnimator = "disableHorizontalAnimator" + const val enableMangaGray = "enableMangaGray" const val autoRefresh = "auto_refresh" const val defaultToRead = "defaultToRead" const val exportCharset = "exportCharset" @@ -180,5 +184,4 @@ object PreferKey { const val showReadTitleAddition = "showReadTitleAddition" const val readBarStyleFollowPage = "readBarStyleFollowPage" const val contentSelectSpeakMod = "contentReadAloudMod" - } 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 ed4924b9f..85b7f9bb0 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 @@ -668,5 +668,31 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener { set(value) { appCtx.putPrefBoolean(PreferKey.hideMangaTitle, value) } + + //开启墨水屏模式 + var enableMangaEInk + get() = appCtx.getPrefBoolean(PreferKey.enableMangaEInk, false) + set(value) { + appCtx.putPrefBoolean(PreferKey.enableMangaEInk, value) + } + + var mangaEInkThreshold + get() = appCtx.getPrefInt(PreferKey.mangaEInkThreshold, 150) + set(value) { + appCtx.putPrefInt(PreferKey.mangaEInkThreshold, value) + } + + var disableHorizontalAnimator + get() = appCtx.getPrefBoolean(PreferKey.disableHorizontalAnimator, false) + set(value) { + appCtx.putPrefBoolean(PreferKey.disableHorizontalAnimator, value) + } + + var enableMangaGray + get() = appCtx.getPrefBoolean(PreferKey.enableMangaGray, false) + set(value) { + appCtx.putPrefBoolean(PreferKey.enableMangaGray, value) + } + } diff --git a/app/src/main/java/io/legado/app/model/BookCover.kt b/app/src/main/java/io/legado/app/model/BookCover.kt index 75dd426f6..f3119a75f 100644 --- a/app/src/main/java/io/legado/app/model/BookCover.kt +++ b/app/src/main/java/io/legado/app/model/BookCover.kt @@ -2,12 +2,14 @@ package io.legado.app.model import android.annotation.SuppressLint import android.content.Context +import android.graphics.Bitmap import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import androidx.annotation.Keep import com.bumptech.glide.Glide import com.bumptech.glide.RequestBuilder import com.bumptech.glide.load.DataSource +import com.bumptech.glide.load.Transformation import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.load.resource.bitmap.CenterCrop @@ -29,6 +31,7 @@ import io.legado.app.help.glide.OkHttpModelLoader import io.legado.app.model.analyzeRule.AnalyzeRule import io.legado.app.model.analyzeRule.AnalyzeRule.Companion.setCoroutineContext import io.legado.app.model.analyzeRule.AnalyzeUrl +import io.legado.app.ui.book.manga.entities.EpaperTransformation import io.legado.app.utils.BitmapUtils import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonObject @@ -86,7 +89,7 @@ object BookCover { path: String?, loadOnlyWifi: Boolean = false, sourceOrigin: String? = null, - onLoadFinish: (() -> Unit)? = null + onLoadFinish: (() -> Unit)? = null, ): RequestBuilder { if (AppConfig.useDefaultCover) { return ImageLoader.load(context, defaultDrawable) @@ -104,7 +107,7 @@ object BookCover { e: GlideException?, model: Any?, target: Target, - isFirstResource: Boolean + isFirstResource: Boolean, ): Boolean { onLoadFinish.invoke() return false @@ -115,7 +118,7 @@ object BookCover { model: Any, target: Target?, dataSource: DataSource, - isFirstResource: Boolean + isFirstResource: Boolean, ): Boolean { onLoadFinish.invoke() return false @@ -130,11 +133,13 @@ object BookCover { /** * 加载漫画图片 */ + @SuppressLint("CheckResult") fun loadManga( context: Context, path: String?, loadOnlyWifi: Boolean = false, sourceOrigin: String? = null, + transformation: Transformation? = null, ): RequestBuilder { var options = RequestOptions().set(OkHttpModelLoader.loadOnlyWifiOption, loadOnlyWifi) .set(OkHttpModelLoader.mangaOption, true) @@ -145,7 +150,12 @@ object BookCover { .apply(options) .override(context.resources.displayMetrics.widthPixels, SIZE_ORIGINAL) .diskCacheStrategy(DiskCacheStrategy.ALL) - .skipMemoryCache(true) + .skipMemoryCache(true).let { + if (transformation != null) { + it.transform(transformation) + } + it + } } fun preloadManga( 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 1ddc9703f..874148a9f 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 @@ -43,6 +43,7 @@ import io.legado.app.ui.book.changesource.ChangeBookSourceDialog import io.legado.app.ui.book.info.BookInfoActivity import io.legado.app.ui.book.manga.config.MangaColorFilterConfig import io.legado.app.ui.book.manga.config.MangaColorFilterDialog +import io.legado.app.ui.book.manga.config.MangaEpaperDialog 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.entities.BaseMangaPage @@ -78,7 +79,7 @@ import kotlin.math.ceil class ReadMangaActivity : VMBaseActivity(), ReadManga.Callback, ChangeBookSourceDialog.CallBack, MangaMenu.CallBack, - MangaColorFilterDialog.Callback, ScrollTimer.ScrollCallback { + MangaColorFilterDialog.Callback, ScrollTimer.ScrollCallback, MangaEpaperDialog.Callback { private val mLayoutManager by lazy { MangaLayoutManager(this) @@ -192,6 +193,8 @@ class ReadMangaActivity : VMBaseActivity { item.isChecked = !item.isChecked AppConfig.enableMangaHorizontalScroll = item.isChecked + mMenu?.findItem(R.id.menu_disable_horizontal_animation)?.isVisible = item.isChecked setHorizontalScroll(item.isChecked) mAdapter.notifyDataSetChanged() } @@ -571,6 +575,38 @@ class ReadMangaActivity : VMBaseActivity { + item.isChecked = !item.isChecked + AppConfig.enableMangaEInk = item.isChecked + mMenu?.findItem(R.id.menu_gray_manga)?.isChecked = false + AppConfig.enableMangaGray = false + mMenu?.findItem(R.id.menu_epaper_manga_setting)?.isVisible = item.isChecked + mAdapter.enableMangaEInk(item.isChecked, AppConfig.mangaEInkThreshold) + } + + R.id.menu_epaper_manga_setting -> { + showDialogFragment(MangaEpaperDialog()) + } + + R.id.menu_disable_horizontal_animation -> { + item.isChecked = !item.isChecked + AppConfig.disableHorizontalAnimator = item.isChecked + if (item.isChecked) { + mPagerSnapHelper.attachToRecyclerView(null) + } else { + mPagerSnapHelper.attachToRecyclerView(binding.recyclerView) + } + } + + R.id.menu_gray_manga -> { + item.isChecked = !item.isChecked + AppConfig.enableMangaGray = item.isChecked + mMenu?.findItem(R.id.menu_epaper_manga)?.isChecked = false + AppConfig.enableMangaEInk = false + mMenu?.findItem(R.id.menu_epaper_manga_setting)?.isVisible = false + mAdapter.enableGray(item.isChecked) + } } return super.onCompatOptionsItemSelected(item) } @@ -626,7 +662,11 @@ class ReadMangaActivity : VMBaseActivity 0 && item.index == item.imageCount - 1 loadImageWithRetry( - item.mImageUrl, isHorizontal, isLastImage + item.mImageUrl, isHorizontal, isLastImage, mTransformation ) } } @@ -100,7 +106,7 @@ class MangaAdapter(private val context: Context) : fun onBind(item: MangaPage) { setImageColorFilter() val isLastImage = item.imageCount > 0 && item.index == item.imageCount - 1 - loadImageWithRetry(item.mImageUrl, isHorizontal, isLastImage) + loadImageWithRetry(item.mImageUrl, isHorizontal, isLastImage, mTransformation) } fun setImageColorFilter() { @@ -167,7 +173,7 @@ class MangaAdapter(private val context: Context) : } } - fun getFooterCount() = footerItems.size() + fun getFooterCount() = footerItems.size private fun isFooter(position: Int) = position >= getActualItemCount() @@ -199,8 +205,8 @@ class MangaAdapter(private val context: Context) : @Synchronized fun addFooterView(footer: ((parent: ViewGroup) -> ViewBinding)) { kotlin.runCatching { - val index = getActualItemCount() + footerItems.size() - footerItems.put(TYPE_FOOTER_VIEW + footerItems.size(), footer) + val index = getActualItemCount() + footerItems.size + footerItems.put(TYPE_FOOTER_VIEW + footerItems.size, footer) notifyItemInserted(index) } } @@ -244,4 +250,31 @@ class MangaAdapter(private val context: Context) : notifyItemRangeChanged(0, itemCount) } + fun enableMangaEInk(enable: Boolean, value: Int) { + if (enable) { + currentMangaEInkThreshold = value + mTransformation = EpaperTransformation(currentMangaEInkThreshold) + } else { + mTransformation = null + } + notifyItemRangeChanged(0, itemCount) + } + + fun updateThreshold(mangaEInkThreshold: Int) { + if (currentMangaEInkThreshold != mangaEInkThreshold) { + currentMangaEInkThreshold = mangaEInkThreshold + mTransformation = EpaperTransformation(currentMangaEInkThreshold) + notifyItemRangeChanged(0, itemCount) + } + } + + //开启灰色图片 + fun enableGray(enable: Boolean) { + mTransformation = if (enable) { + GrayscaleTransformation() + } else { + null + } + notifyItemRangeChanged(0, itemCount) + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/manga/recyclerview/MangaVH.kt b/app/src/main/java/io/legado/app/ui/book/manga/recyclerview/MangaVH.kt index c6528853e..ef1929003 100644 --- a/app/src/main/java/io/legado/app/ui/book/manga/recyclerview/MangaVH.kt +++ b/app/src/main/java/io/legado/app/ui/book/manga/recyclerview/MangaVH.kt @@ -2,6 +2,7 @@ package io.legado.app.ui.book.manga.recyclerview import android.annotation.SuppressLint import android.content.Context +import android.graphics.Bitmap import android.graphics.drawable.Drawable import android.view.Gravity import android.view.ViewGroup @@ -17,6 +18,7 @@ import androidx.core.view.updateLayoutParams import androidx.recyclerview.widget.RecyclerView import androidx.viewbinding.ViewBinding import com.bumptech.glide.load.DataSource +import com.bumptech.glide.load.Transformation import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.target.Target @@ -51,7 +53,7 @@ open class MangaVH(val binding: VB, private val context: Conte } @SuppressLint("CheckResult") - fun loadImageWithRetry(imageUrl: String, isHorizontal: Boolean, isLastImage: Boolean) { + fun loadImageWithRetry(imageUrl: String, isHorizontal: Boolean, isLastImage: Boolean,transformation: Transformation?) { mFlProgress.isVisible = true mLoading.isVisible = true mRetry?.isGone = true @@ -67,6 +69,7 @@ open class MangaVH(val binding: VB, private val context: Conte context, imageUrl, sourceOrigin = ReadManga.book?.origin, + transformation = transformation ).addListener(object : RequestListener { override fun onLoadFailed( e: GlideException?, diff --git a/app/src/main/res/layout/dialog_manga_color_filter.xml b/app/src/main/res/layout/dialog_manga_color_filter.xml index 9c5b77e40..834d39af3 100644 --- a/app/src/main/res/layout/dialog_manga_color_filter.xml +++ b/app/src/main/res/layout/dialog_manga_color_filter.xml @@ -14,7 +14,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingBottom="8dp" - android:text="滤镜" + android:text="@string/manga_color_filter" android:textSize="18sp" /> + + + + + + + + + + + diff --git a/app/src/main/res/menu/book_manga.xml b/app/src/main/res/menu/book_manga.xml index 6a1a8b724..2c7020f0d 100644 --- a/app/src/main/res/menu/book_manga.xml +++ b/app/src/main/res/menu/book_manga.xml @@ -71,6 +71,14 @@ android:title="@string/enable_manga_horizontal_scroll" 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 1a590cb5a..fc93d7861 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -1216,4 +1216,9 @@ 隐藏漫画列表标题 刷新发现 Padding display cutouts + 墨水屏 + 墨水屏设置 + 阈值 + 禁用水平滚动动画 + 开启图片灰色灰色 diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 1febb2666..07c1b6acc 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -1219,4 +1219,9 @@ 隐藏漫画列表标题 刷新发现 Padding display cutouts + 墨水屏 + 墨水屏设置 + 阈值 + 禁用水平滚动动画 + 开启图片灰色 diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 37b348097..5afdac668 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -1219,4 +1219,9 @@ 隐藏漫画列表标题 刷新发现 Padding display cutouts + 墨水屏 + 墨水屏设置 + 阈值 + 禁用水平滚动动画 + 开启图片灰色 diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 95d6e33c5..ebadf86bc 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -1215,4 +1215,9 @@ Còn 隐藏漫画列表标题 刷新发现 Padding display cutouts + 墨水屏 + 墨水屏设置 + 阈值 + 禁用水平滚动动画 + 开启图片灰色 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index da30d6dee..35692e68f 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -1214,4 +1214,9 @@ 系統媒體控件相容性更改 當鎖屏不顯示系統媒體控件時可以嘗試開啟,比如 OneUI7.0 或 vivo 等 朗讀暫停/繼續 + 墨水屏 + 墨水屏设置 + 阈值 + 禁用水平滚动动画 + 开启图片灰色 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index d657064e8..3ece125b2 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1216,4 +1216,8 @@ 系統媒體控件相容性更改 當鎖屏不顯示系統媒體控件時可以嘗試開啟,比如 OneUI7.0 或 vivo 等 朗讀暫停/繼續 + 墨水屏 + 阈值 + 禁用水平滚动动画 + 开启图片灰色 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 0fd571b70..42575e6d1 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -1221,4 +1221,9 @@ 系统媒体控件兼容性更改 当锁屏不显示系统媒体控件时可以尝试开启,比如oneui7.0或vivo等 朗读暂停/继续 + 墨水屏 + 墨水屏设置 + 阈值 + 禁用水平滚动动画 + 开启图片灰色 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8a88e6ed0..b52dc887e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1222,4 +1222,9 @@ System Media Control Compatibility Change If system media controls do not appear on the lock screen, you can try enabling this, for example on OneUI 7.0 or Vivo devices. Pause/Resume Speech + 墨水屏 + 墨水屏设置 + 阈值 + 禁用水平滚动动画 + 开启图片灰色