@@ -104,6 +104,11 @@ object PreferKey {
|
|||||||
const val enableMangaHorizontalScroll = "enableMangaHorizontalScroll"
|
const val enableMangaHorizontalScroll = "enableMangaHorizontalScroll"
|
||||||
const val hideMangaTitle = "hideMangaTitle"
|
const val hideMangaTitle = "hideMangaTitle"
|
||||||
const val mangaColorFilter = "mangaColorFilter"
|
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 autoRefresh = "auto_refresh"
|
||||||
const val defaultToRead = "defaultToRead"
|
const val defaultToRead = "defaultToRead"
|
||||||
const val exportCharset = "exportCharset"
|
const val exportCharset = "exportCharset"
|
||||||
|
|||||||
@@ -496,7 +496,7 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
|||||||
|
|
||||||
val defaultHomePage get() = appCtx.getPrefString(PreferKey.defaultHomePage, "bookshelf")
|
val defaultHomePage get() = appCtx.getPrefString(PreferKey.defaultHomePage, "bookshelf")
|
||||||
|
|
||||||
val updateToVariant get() = appCtx.getPrefString(PreferKey.updateToVariant, "default_version")
|
val updateToVariant get() = appCtx.getPrefString(PreferKey.updateToVariant, "official_version")
|
||||||
|
|
||||||
val streamReadAloudAudio get() = appCtx.getPrefBoolean(PreferKey.streamReadAloudAudio, false)
|
val streamReadAloudAudio get() = appCtx.getPrefBoolean(PreferKey.streamReadAloudAudio, false)
|
||||||
|
|
||||||
@@ -676,5 +676,30 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
|||||||
set(value) {
|
set(value) {
|
||||||
appCtx.putPrefBoolean(PreferKey.hideMangaTitle, 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ package io.legato.kazusa.model
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.Bitmap
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
|
import androidx.core.graphics.drawable.toDrawable
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.RequestBuilder
|
import com.bumptech.glide.RequestBuilder
|
||||||
import com.bumptech.glide.load.DataSource
|
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.DiskCacheStrategy
|
||||||
import com.bumptech.glide.load.engine.GlideException
|
import com.bumptech.glide.load.engine.GlideException
|
||||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
||||||
@@ -74,7 +76,7 @@ object BookCover {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defaultDrawable = kotlin.runCatching {
|
defaultDrawable = kotlin.runCatching {
|
||||||
BitmapDrawable(appCtx.resources, BitmapUtils.decodeBitmap(path, 600, 900))
|
BitmapUtils.decodeBitmap(path, 600, 900).toDrawable(appCtx.resources)
|
||||||
}.getOrDefault(appCtx.resources.getDrawable(R.drawable.image_cover_default, null))
|
}.getOrDefault(appCtx.resources.getDrawable(R.drawable.image_cover_default, null))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +89,7 @@ object BookCover {
|
|||||||
path: String?,
|
path: String?,
|
||||||
loadOnlyWifi: Boolean = false,
|
loadOnlyWifi: Boolean = false,
|
||||||
sourceOrigin: String? = null,
|
sourceOrigin: String? = null,
|
||||||
onLoadFinish: (() -> Unit)? = null
|
onLoadFinish: (() -> Unit)? = null,
|
||||||
): RequestBuilder<Drawable> {
|
): RequestBuilder<Drawable> {
|
||||||
if (AppConfig.useDefaultCover) {
|
if (AppConfig.useDefaultCover) {
|
||||||
return ImageLoader.load(context, defaultDrawable)
|
return ImageLoader.load(context, defaultDrawable)
|
||||||
@@ -105,7 +107,7 @@ object BookCover {
|
|||||||
e: GlideException?,
|
e: GlideException?,
|
||||||
model: Any?,
|
model: Any?,
|
||||||
target: Target<Drawable?>,
|
target: Target<Drawable?>,
|
||||||
isFirstResource: Boolean
|
isFirstResource: Boolean,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
onLoadFinish.invoke()
|
onLoadFinish.invoke()
|
||||||
return false
|
return false
|
||||||
@@ -116,7 +118,7 @@ object BookCover {
|
|||||||
model: Any,
|
model: Any,
|
||||||
target: Target<Drawable?>?,
|
target: Target<Drawable?>?,
|
||||||
dataSource: DataSource,
|
dataSource: DataSource,
|
||||||
isFirstResource: Boolean
|
isFirstResource: Boolean,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
onLoadFinish.invoke()
|
onLoadFinish.invoke()
|
||||||
return false
|
return false
|
||||||
@@ -133,11 +135,13 @@ object BookCover {
|
|||||||
/**
|
/**
|
||||||
* 加载漫画图片
|
* 加载漫画图片
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("CheckResult")
|
||||||
fun loadManga(
|
fun loadManga(
|
||||||
context: Context,
|
context: Context,
|
||||||
path: String?,
|
path: String?,
|
||||||
loadOnlyWifi: Boolean = false,
|
loadOnlyWifi: Boolean = false,
|
||||||
sourceOrigin: String? = null,
|
sourceOrigin: String? = null,
|
||||||
|
transformation: Transformation<Bitmap>? = null,
|
||||||
): RequestBuilder<Drawable> {
|
): RequestBuilder<Drawable> {
|
||||||
var options = RequestOptions().set(OkHttpModelLoader.loadOnlyWifiOption, loadOnlyWifi)
|
var options = RequestOptions().set(OkHttpModelLoader.loadOnlyWifiOption, loadOnlyWifi)
|
||||||
.set(OkHttpModelLoader.mangaOption, true)
|
.set(OkHttpModelLoader.mangaOption, true)
|
||||||
@@ -148,7 +152,12 @@ object BookCover {
|
|||||||
.apply(options)
|
.apply(options)
|
||||||
.override(context.resources.displayMetrics.widthPixels, SIZE_ORIGINAL)
|
.override(context.resources.displayMetrics.widthPixels, SIZE_ORIGINAL)
|
||||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
.skipMemoryCache(true)
|
.skipMemoryCache(true).let {
|
||||||
|
if (transformation != null) {
|
||||||
|
it.transform(transformation)
|
||||||
|
}
|
||||||
|
it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun preloadManga(
|
fun preloadManga(
|
||||||
|
|||||||
@@ -6,8 +6,11 @@ import android.view.View
|
|||||||
import io.legato.kazusa.BuildConfig
|
import io.legato.kazusa.BuildConfig
|
||||||
import io.legato.kazusa.R
|
import io.legato.kazusa.R
|
||||||
import io.legato.kazusa.base.BaseBottomSheetDialogFragment
|
import io.legato.kazusa.base.BaseBottomSheetDialogFragment
|
||||||
|
import io.legato.kazusa.constant.AppConst
|
||||||
import io.legato.kazusa.databinding.DialogUpdateBinding
|
import io.legato.kazusa.databinding.DialogUpdateBinding
|
||||||
|
import io.legato.kazusa.help.config.AppConfig
|
||||||
import io.legato.kazusa.help.update.AppUpdate
|
import io.legato.kazusa.help.update.AppUpdate
|
||||||
|
import io.legato.kazusa.help.update.AppVariant
|
||||||
import io.legato.kazusa.model.Download
|
import io.legato.kazusa.model.Download
|
||||||
import io.legato.kazusa.utils.toastOnUi
|
import io.legato.kazusa.utils.toastOnUi
|
||||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||||
@@ -27,6 +30,14 @@ class UpdateDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_update) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val checkVariant: AppVariant
|
||||||
|
get() = when (AppConfig.updateToVariant) {
|
||||||
|
"official_version" -> AppVariant.OFFICIAL
|
||||||
|
"beta_release_version" -> AppVariant.BETA_RELEASE
|
||||||
|
"beta_releaseA_version" -> AppVariant.BETA_RELEASEA
|
||||||
|
else -> AppConst.appInfo.appVariant
|
||||||
|
}
|
||||||
|
|
||||||
val binding by viewBinding(DialogUpdateBinding::bind)
|
val binding by viewBinding(DialogUpdateBinding::bind)
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
@@ -41,6 +52,7 @@ class UpdateDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_update) {
|
|||||||
|
|
||||||
binding.tvAbi.text = Build.SUPPORTED_ABIS.firstOrNull() ?: "unknown"
|
binding.tvAbi.text = Build.SUPPORTED_ABIS.firstOrNull() ?: "unknown"
|
||||||
binding.tvUrl.text = arguments?.getString("url")
|
binding.tvUrl.text = arguments?.getString("url")
|
||||||
|
binding.tvVariable.text = checkVariant.toString()
|
||||||
|
|
||||||
val updateBody = arguments?.getString("updateBody")
|
val updateBody = arguments?.getString("updateBody")
|
||||||
if (updateBody == null) {
|
if (updateBody == null) {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import android.content.Intent
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.os.PersistableBundle
|
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
@@ -44,6 +43,7 @@ import io.legato.kazusa.ui.book.changesource.ChangeBookSourceDialog
|
|||||||
import io.legato.kazusa.ui.book.info.BookInfoActivity
|
import io.legato.kazusa.ui.book.info.BookInfoActivity
|
||||||
import io.legato.kazusa.ui.book.manga.config.MangaColorFilterConfig
|
import io.legato.kazusa.ui.book.manga.config.MangaColorFilterConfig
|
||||||
import io.legato.kazusa.ui.book.manga.config.MangaColorFilterDialog
|
import io.legato.kazusa.ui.book.manga.config.MangaColorFilterDialog
|
||||||
|
import io.legato.kazusa.ui.book.manga.config.MangaEpaperDialog
|
||||||
import io.legato.kazusa.ui.book.manga.config.MangaFooterConfig
|
import io.legato.kazusa.ui.book.manga.config.MangaFooterConfig
|
||||||
import io.legato.kazusa.ui.book.manga.config.MangaFooterSettingDialog
|
import io.legato.kazusa.ui.book.manga.config.MangaFooterSettingDialog
|
||||||
import io.legato.kazusa.ui.book.manga.entities.BaseMangaPage
|
import io.legato.kazusa.ui.book.manga.entities.BaseMangaPage
|
||||||
@@ -63,7 +63,6 @@ import io.legato.kazusa.utils.canScroll
|
|||||||
import io.legato.kazusa.utils.fastBinarySearch
|
import io.legato.kazusa.utils.fastBinarySearch
|
||||||
import io.legato.kazusa.utils.findCenterViewPosition
|
import io.legato.kazusa.utils.findCenterViewPosition
|
||||||
import io.legato.kazusa.utils.fromJsonObject
|
import io.legato.kazusa.utils.fromJsonObject
|
||||||
import io.legato.kazusa.utils.getCompatColor
|
|
||||||
import io.legato.kazusa.utils.gone
|
import io.legato.kazusa.utils.gone
|
||||||
import io.legato.kazusa.utils.observeEvent
|
import io.legato.kazusa.utils.observeEvent
|
||||||
import io.legato.kazusa.utils.showDialogFragment
|
import io.legato.kazusa.utils.showDialogFragment
|
||||||
@@ -79,7 +78,7 @@ import kotlin.math.ceil
|
|||||||
|
|
||||||
class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewModel>(),
|
class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewModel>(),
|
||||||
ReadManga.Callback, ChangeBookSourceDialog.CallBack, MangaMenu.CallBack,
|
ReadManga.Callback, ChangeBookSourceDialog.CallBack, MangaMenu.CallBack,
|
||||||
MangaColorFilterDialog.Callback, ScrollTimer.ScrollCallback {
|
MangaColorFilterDialog.Callback, ScrollTimer.ScrollCallback, MangaEpaperDialog.Callback {
|
||||||
|
|
||||||
private val mLayoutManager by lazy {
|
private val mLayoutManager by lazy {
|
||||||
MangaLayoutManager(this)
|
MangaLayoutManager(this)
|
||||||
@@ -191,6 +190,8 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
|
|||||||
?: MangaColorFilterConfig()
|
?: MangaColorFilterConfig()
|
||||||
mAdapter.run {
|
mAdapter.run {
|
||||||
setMangaImageColorFilter(mangaColorFilter)
|
setMangaImageColorFilter(mangaColorFilter)
|
||||||
|
enableMangaEInk(AppConfig.enableMangaEInk, AppConfig.mangaEInkThreshold)
|
||||||
|
enableGray(AppConfig.enableMangaGray)
|
||||||
}
|
}
|
||||||
setHorizontalScroll(AppConfig.enableMangaHorizontalScroll)
|
setHorizontalScroll(AppConfig.enableMangaHorizontalScroll)
|
||||||
binding.recyclerView.run {
|
binding.recyclerView.run {
|
||||||
@@ -541,6 +542,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
|
|||||||
R.id.menu_enable_horizontal_scroll -> {
|
R.id.menu_enable_horizontal_scroll -> {
|
||||||
item.isChecked = !item.isChecked
|
item.isChecked = !item.isChecked
|
||||||
AppConfig.enableMangaHorizontalScroll = item.isChecked
|
AppConfig.enableMangaHorizontalScroll = item.isChecked
|
||||||
|
mMenu?.findItem(R.id.menu_disable_horizontal_animation)?.isVisible = item.isChecked
|
||||||
setHorizontalScroll(item.isChecked)
|
setHorizontalScroll(item.isChecked)
|
||||||
mAdapter.notifyDataSetChanged()
|
mAdapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
@@ -570,6 +572,38 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
|
|||||||
AppConfig.hideMangaTitle = item.isChecked
|
AppConfig.hideMangaTitle = item.isChecked
|
||||||
ReadManga.loadContent()
|
ReadManga.loadContent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.menu_epaper_manga -> {
|
||||||
|
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)
|
return super.onCompatOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
@@ -626,6 +660,11 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
|
|||||||
if (enable) {
|
if (enable) {
|
||||||
if (!enableAutoScroll) {
|
if (!enableAutoScroll) {
|
||||||
mPagerSnapHelper.attachToRecyclerView(binding.recyclerView)
|
mPagerSnapHelper.attachToRecyclerView(binding.recyclerView)
|
||||||
|
if (AppConfig.disableHorizontalAnimator) {
|
||||||
|
mPagerSnapHelper.attachToRecyclerView(null)
|
||||||
|
} else {
|
||||||
|
mPagerSnapHelper.attachToRecyclerView(binding.recyclerView)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mLayoutManager.orientation = LinearLayoutManager.HORIZONTAL
|
mLayoutManager.orientation = LinearLayoutManager.HORIZONTAL
|
||||||
} else {
|
} else {
|
||||||
@@ -646,6 +685,14 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
|
|||||||
menu.findItem(R.id.menu_enable_horizontal_scroll).isChecked =
|
menu.findItem(R.id.menu_enable_horizontal_scroll).isChecked =
|
||||||
AppConfig.enableMangaHorizontalScroll
|
AppConfig.enableMangaHorizontalScroll
|
||||||
menu.findItem(R.id.menu_hide_manga_title).isChecked = AppConfig.hideMangaTitle
|
menu.findItem(R.id.menu_hide_manga_title).isChecked = AppConfig.hideMangaTitle
|
||||||
|
menu.findItem(R.id.menu_epaper_manga).isChecked = AppConfig.enableMangaEInk
|
||||||
|
menu.findItem(R.id.menu_epaper_manga_setting).isVisible = AppConfig.enableMangaEInk
|
||||||
|
menu.findItem(R.id.menu_disable_horizontal_animation).run {
|
||||||
|
isVisible =
|
||||||
|
AppConfig.enableMangaHorizontalScroll
|
||||||
|
isChecked = AppConfig.disableHorizontalAnimator
|
||||||
|
}
|
||||||
|
menu.findItem(R.id.menu_gray_manga).isChecked = AppConfig.enableMangaGray
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setDisableMangaScale(disable: Boolean) {
|
private fun setDisableMangaScale(disable: Boolean) {
|
||||||
@@ -784,4 +831,8 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
|
|||||||
}
|
}
|
||||||
return super.onKeyDown(keyCode, event)
|
return super.onKeyDown(keyCode, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun updateEepaper(value: Int) {
|
||||||
|
mAdapter.updateThreshold(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package io.legato.kazusa.ui.book.manga.config
|
||||||
|
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import io.legato.kazusa.R
|
||||||
|
import io.legato.kazusa.base.BaseBottomSheetDialogFragment
|
||||||
|
import io.legato.kazusa.databinding.DialogMangaEpaperBinding
|
||||||
|
import io.legato.kazusa.help.config.AppConfig
|
||||||
|
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||||
|
|
||||||
|
|
||||||
|
class MangaEpaperDialog : BaseBottomSheetDialogFragment(R.layout.dialog_manga_epaper) {
|
||||||
|
private val binding by viewBinding(DialogMangaEpaperBinding::bind)
|
||||||
|
private val callback get() = activity as? Callback
|
||||||
|
private var mMangaEInkThreshold = 150
|
||||||
|
|
||||||
|
// override fun onStart() {
|
||||||
|
// super.onStart()
|
||||||
|
// dialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
|
||||||
|
// setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
|
// }
|
||||||
|
|
||||||
|
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
initData()
|
||||||
|
initView()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initData() {
|
||||||
|
binding.dsbEpaper.progress = AppConfig.mangaEInkThreshold
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initView() {
|
||||||
|
binding.dsbEpaper.onChanged = {
|
||||||
|
mMangaEInkThreshold = it
|
||||||
|
callback?.updateEepaper(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss(dialog: DialogInterface) {
|
||||||
|
super.onDismiss(dialog)
|
||||||
|
AppConfig.mangaEInkThreshold = mMangaEInkThreshold
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Callback {
|
||||||
|
fun updateEepaper(value: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package io.legato.kazusa.ui.book.manga.entities
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.ColorMatrix
|
||||||
|
import android.graphics.ColorMatrixColorFilter
|
||||||
|
import android.graphics.Paint
|
||||||
|
import androidx.annotation.IntRange
|
||||||
|
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||||
|
import java.security.MessageDigest
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 墨水屏图片转换器。
|
||||||
|
* 将彩色图片转换为灰度图,并可选择进行简单的二值化处理,以提高墨水屏显示效果。
|
||||||
|
*
|
||||||
|
* @param threshold 二值化的阈值(0-255)。低于此值的像素变为黑色,高于此值的像素变为白色。
|
||||||
|
* 仅当applyBinarization为true时有效。
|
||||||
|
*/
|
||||||
|
class EpaperTransformation(
|
||||||
|
@IntRange(0, 255) private val threshold: Int = 128,
|
||||||
|
) : BitmapTransformation() {
|
||||||
|
|
||||||
|
private val ID =
|
||||||
|
"io.legado.app.model.EpaperTransformation.${threshold}"
|
||||||
|
private val ID_BYTES = ID.toByteArray(CHARSET)
|
||||||
|
|
||||||
|
override fun transform(
|
||||||
|
pool: BitmapPool,
|
||||||
|
toTransform: Bitmap,
|
||||||
|
outWidth: Int,
|
||||||
|
outHeight: Int,
|
||||||
|
): Bitmap {
|
||||||
|
val resultBitmap = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888)
|
||||||
|
val canvas = Canvas(resultBitmap)
|
||||||
|
val paint = Paint()
|
||||||
|
|
||||||
|
val colorMatrix = ColorMatrix()
|
||||||
|
colorMatrix.setSaturation(0f)
|
||||||
|
val filter = ColorMatrixColorFilter(colorMatrix)
|
||||||
|
paint.colorFilter = filter
|
||||||
|
canvas.drawBitmap(toTransform, 0f, 0f, paint)
|
||||||
|
|
||||||
|
val pixels = IntArray(outWidth * outHeight)
|
||||||
|
resultBitmap.getPixels(pixels, 0, outWidth, 0, 0, outWidth, outHeight)
|
||||||
|
|
||||||
|
for (i in pixels.indices) {
|
||||||
|
val pixel = pixels[i]
|
||||||
|
val gray = Color.red(pixel)
|
||||||
|
pixels[i] =
|
||||||
|
if (gray < threshold) Color.BLACK else Color.WHITE
|
||||||
|
}
|
||||||
|
resultBitmap.setPixels(pixels, 0, outWidth, 0, 0, outWidth, outHeight)
|
||||||
|
|
||||||
|
return resultBitmap
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
|
||||||
|
messageDigest.update(ID_BYTES)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as EpaperTransformation
|
||||||
|
|
||||||
|
if (threshold != other.threshold) return false
|
||||||
|
if (ID != other.ID) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = 31 + threshold
|
||||||
|
result = 31 * result + ID.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package io.legato.kazusa.ui.book.manga.entities
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.ColorMatrix
|
||||||
|
import android.graphics.ColorMatrixColorFilter
|
||||||
|
import android.graphics.Paint
|
||||||
|
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.security.MessageDigest
|
||||||
|
|
||||||
|
class GrayscaleTransformation : BitmapTransformation() {
|
||||||
|
private val ID = "io.legado.app.model.GrayscaleTransformation"
|
||||||
|
|
||||||
|
private val ID_BYTES = ID.toByteArray(StandardCharsets.UTF_8)
|
||||||
|
|
||||||
|
override fun transform(
|
||||||
|
pool: BitmapPool,
|
||||||
|
toTransform: Bitmap,
|
||||||
|
outWidth: Int,
|
||||||
|
outHeight: Int,
|
||||||
|
): Bitmap {
|
||||||
|
val resultBitmap = pool.get(outWidth, outHeight, Bitmap.Config.ARGB_8888)
|
||||||
|
|
||||||
|
val canvas = Canvas(resultBitmap)
|
||||||
|
val paint = Paint()
|
||||||
|
|
||||||
|
val matrix = ColorMatrix(
|
||||||
|
floatArrayOf(
|
||||||
|
0.299f, 0.587f, 0.114f, 0f, 0f,
|
||||||
|
0.299f, 0.587f, 0.114f, 0f, 0f,
|
||||||
|
0.299f, 0.587f, 0.114f, 0f, 0f,
|
||||||
|
0f, 0f, 0f, 1f, 0f
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val filter = ColorMatrixColorFilter(matrix)
|
||||||
|
paint.colorFilter = filter
|
||||||
|
canvas.drawBitmap(toTransform, 0f, 0f, paint)
|
||||||
|
return resultBitmap
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
|
||||||
|
messageDigest.update(ID_BYTES)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
other as GrayscaleTransformation
|
||||||
|
return ID == other.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return ID.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import android.view.LayoutInflater
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
import androidx.annotation.IntRange
|
import androidx.annotation.IntRange
|
||||||
|
import androidx.core.util.size
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.recyclerview.widget.AsyncListDiffer
|
import androidx.recyclerview.widget.AsyncListDiffer
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
@@ -16,6 +17,7 @@ import androidx.viewbinding.ViewBinding
|
|||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.ListPreloader.PreloadModelProvider
|
import com.bumptech.glide.ListPreloader.PreloadModelProvider
|
||||||
import com.bumptech.glide.RequestBuilder
|
import com.bumptech.glide.RequestBuilder
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||||
import io.legato.kazusa.base.adapter.ItemViewHolder
|
import io.legato.kazusa.base.adapter.ItemViewHolder
|
||||||
import io.legato.kazusa.base.adapter.RecyclerAdapter.Companion.TYPE_FOOTER_VIEW
|
import io.legato.kazusa.base.adapter.RecyclerAdapter.Companion.TYPE_FOOTER_VIEW
|
||||||
import io.legato.kazusa.databinding.ItemBookMangaEdgeBinding
|
import io.legato.kazusa.databinding.ItemBookMangaEdgeBinding
|
||||||
@@ -24,6 +26,8 @@ import io.legato.kazusa.help.glide.progress.ProgressManager
|
|||||||
import io.legato.kazusa.model.BookCover
|
import io.legato.kazusa.model.BookCover
|
||||||
import io.legato.kazusa.model.ReadManga
|
import io.legato.kazusa.model.ReadManga
|
||||||
import io.legato.kazusa.ui.book.manga.config.MangaColorFilterConfig
|
import io.legato.kazusa.ui.book.manga.config.MangaColorFilterConfig
|
||||||
|
import io.legato.kazusa.ui.book.manga.entities.EpaperTransformation
|
||||||
|
import io.legato.kazusa.ui.book.manga.entities.GrayscaleTransformation
|
||||||
import io.legato.kazusa.ui.book.manga.entities.MangaPage
|
import io.legato.kazusa.ui.book.manga.entities.MangaPage
|
||||||
import io.legato.kazusa.ui.book.manga.entities.ReaderLoading
|
import io.legato.kazusa.ui.book.manga.entities.ReaderLoading
|
||||||
import io.legato.kazusa.utils.dpToPx
|
import io.legato.kazusa.utils.dpToPx
|
||||||
@@ -34,6 +38,8 @@ class MangaAdapter(private val context: Context) :
|
|||||||
|
|
||||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||||
private lateinit var mConfig: MangaColorFilterConfig
|
private lateinit var mConfig: MangaColorFilterConfig
|
||||||
|
private var mTransformation: BitmapTransformation? = null
|
||||||
|
private var currentMangaEInkThreshold = 0
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val LOADING_VIEW = 0
|
private const val LOADING_VIEW = 0
|
||||||
@@ -91,7 +97,7 @@ class MangaAdapter(private val context: Context) :
|
|||||||
if (item is MangaPage) {
|
if (item is MangaPage) {
|
||||||
val isLastImage = item.imageCount > 0 && item.index == item.imageCount - 1
|
val isLastImage = item.imageCount > 0 && item.index == item.imageCount - 1
|
||||||
loadImageWithRetry(
|
loadImageWithRetry(
|
||||||
item.mImageUrl, isHorizontal, isLastImage
|
item.mImageUrl, isHorizontal, isLastImage, mTransformation
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +106,7 @@ class MangaAdapter(private val context: Context) :
|
|||||||
fun onBind(item: MangaPage) {
|
fun onBind(item: MangaPage) {
|
||||||
setImageColorFilter()
|
setImageColorFilter()
|
||||||
val isLastImage = item.imageCount > 0 && item.index == item.imageCount - 1
|
val isLastImage = item.imageCount > 0 && item.index == item.imageCount - 1
|
||||||
loadImageWithRetry(item.mImageUrl, isHorizontal, isLastImage)
|
loadImageWithRetry(item.mImageUrl, isHorizontal, isLastImage, mTransformation)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setImageColorFilter() {
|
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()
|
private fun isFooter(position: Int) = position >= getActualItemCount()
|
||||||
|
|
||||||
@@ -199,8 +205,8 @@ class MangaAdapter(private val context: Context) :
|
|||||||
@Synchronized
|
@Synchronized
|
||||||
fun addFooterView(footer: ((parent: ViewGroup) -> ViewBinding)) {
|
fun addFooterView(footer: ((parent: ViewGroup) -> ViewBinding)) {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
val index = getActualItemCount() + footerItems.size()
|
val index = getActualItemCount() + footerItems.size
|
||||||
footerItems.put(TYPE_FOOTER_VIEW + footerItems.size(), footer)
|
footerItems.put(TYPE_FOOTER_VIEW + footerItems.size, footer)
|
||||||
notifyItemInserted(index)
|
notifyItemInserted(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,4 +250,32 @@ class MangaAdapter(private val context: Context) :
|
|||||||
notifyItemRangeChanged(0, itemCount)
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package io.legato.kazusa.ui.book.manga.recyclerview
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@@ -17,6 +18,7 @@ import androidx.core.view.updateLayoutParams
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import com.bumptech.glide.load.DataSource
|
import com.bumptech.glide.load.DataSource
|
||||||
|
import com.bumptech.glide.load.Transformation
|
||||||
import com.bumptech.glide.load.engine.GlideException
|
import com.bumptech.glide.load.engine.GlideException
|
||||||
import com.bumptech.glide.request.RequestListener
|
import com.bumptech.glide.request.RequestListener
|
||||||
import com.bumptech.glide.request.target.Target
|
import com.bumptech.glide.request.target.Target
|
||||||
@@ -51,7 +53,12 @@ open class MangaVH<VB : ViewBinding>(val binding: VB, private val context: Conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
fun loadImageWithRetry(imageUrl: String, isHorizontal: Boolean, isLastImage: Boolean) {
|
fun loadImageWithRetry(
|
||||||
|
imageUrl: String,
|
||||||
|
isHorizontal: Boolean,
|
||||||
|
isLastImage: Boolean,
|
||||||
|
transformation: Transformation<Bitmap>?
|
||||||
|
) {
|
||||||
mFlProgress.isVisible = true
|
mFlProgress.isVisible = true
|
||||||
mLoading.isVisible = true
|
mLoading.isVisible = true
|
||||||
mRetry?.isGone = true
|
mRetry?.isGone = true
|
||||||
@@ -67,6 +74,7 @@ open class MangaVH<VB : ViewBinding>(val binding: VB, private val context: Conte
|
|||||||
context,
|
context,
|
||||||
imageUrl,
|
imageUrl,
|
||||||
sourceOrigin = ReadManga.book?.origin,
|
sourceOrigin = ReadManga.book?.origin,
|
||||||
|
transformation = transformation
|
||||||
).addListener(object : RequestListener<Drawable> {
|
).addListener(object : RequestListener<Drawable> {
|
||||||
override fun onLoadFailed(
|
override fun onLoadFailed(
|
||||||
e: GlideException?,
|
e: GlideException?,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingBottom="8dp"
|
android:paddingBottom="8dp"
|
||||||
android:text="滤镜"
|
android:text="@string/manga_color_filter"
|
||||||
android:textSize="18sp" />
|
android:textSize="18sp" />
|
||||||
|
|
||||||
<io.legato.kazusa.ui.widget.DetailSeekBar
|
<io.legato.kazusa.ui.widget.DetailSeekBar
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:text="@string/manga_epaper_stting"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<io.legato.kazusa.ui.widget.DetailSeekBar
|
||||||
|
android:id="@+id/dsb_epaper"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:max="255"
|
||||||
|
app:title="@string/manga_epaper_value" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
@@ -98,21 +98,52 @@
|
|||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:strokeWidth="0dp"
|
app:cardBackgroundColor="?attr/colorPrimaryContainer"
|
||||||
app:cardBackgroundColor="?attr/colorPrimaryContainer">
|
app:strokeWidth="0dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_abi"
|
android:id="@+id/tv_abi"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:text="ABI: arm64-v8a"
|
android:text="ABI: arm64-v8a"
|
||||||
android:textColor="?attr/colorOnSurfaceVariant"
|
android:textAppearance="?attr/textAppearanceBodySmall"
|
||||||
android:textAppearance="?attr/textAppearanceBodySmall" />
|
android:textColor="?attr/colorOnSurfaceVariant" />
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginHorizontal="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="?attr/colorSecondary" />
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardBackgroundColor="?attr/colorPrimaryContainer"
|
||||||
|
app:strokeWidth="0dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_variable"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:text="123"
|
||||||
|
android:textAppearance="?attr/textAppearanceBodyMedium" />
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_url"
|
android:id="@+id/tv_url"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -71,6 +71,14 @@
|
|||||||
android:title="@string/enable_manga_horizontal_scroll"
|
android:title="@string/enable_manga_horizontal_scroll"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_disable_horizontal_animation"
|
||||||
|
android:checkable="true"
|
||||||
|
android:checked="false"
|
||||||
|
android:title="@string/disable_horizontal_animation"
|
||||||
|
android:visible="false"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_manga_footer_config"
|
android:id="@+id/menu_manga_footer_config"
|
||||||
android:title="@string/manga_footer_config"
|
android:title="@string/manga_footer_config"
|
||||||
@@ -88,4 +96,24 @@
|
|||||||
android:title="@string/hide_manga_title"
|
android:title="@string/hide_manga_title"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_epaper_manga"
|
||||||
|
android:checkable="true"
|
||||||
|
android:checked="false"
|
||||||
|
android:title="@string/manga_epaper"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_epaper_manga_setting"
|
||||||
|
android:title="@string/manga_epaper_stting"
|
||||||
|
android:visible="false"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_gray_manga"
|
||||||
|
android:checkable="true"
|
||||||
|
android:checked="false"
|
||||||
|
android:title="@string/enable_manga_gray"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
|||||||
@@ -1217,8 +1217,18 @@
|
|||||||
<string name="manga_color_filter">滤镜</string>
|
<string name="manga_color_filter">滤镜</string>
|
||||||
<string name="hide_manga_title">隐藏漫画列表标题</string>
|
<string name="hide_manga_title">隐藏漫画列表标题</string>
|
||||||
<string name="refresh_explore">刷新发现</string>
|
<string name="refresh_explore">刷新发现</string>
|
||||||
|
<string name="ungroup">未分组</string>
|
||||||
|
<string name="dynamic_colors">动态取色</string>
|
||||||
<string name="change_icon_success">图标已修改</string>
|
<string name="change_icon_success">图标已修改</string>
|
||||||
|
<string name="replace_rule_title_setting">配置替换规则</string>
|
||||||
|
<string name="more_setting">更多设置</string>
|
||||||
<string name="read_chapter_total">共 %d 章</string>
|
<string name="read_chapter_total">共 %d 章</string>
|
||||||
<string name="read_chapter_index">已读 %d 章</string>
|
<string name="read_chapter_index">已读 %d 章</string>
|
||||||
|
|
||||||
|
<string name="manga_epaper">墨水屏</string>
|
||||||
|
<string name="manga_epaper_stting">墨水屏设置</string>
|
||||||
|
<string name="manga_epaper_value">阈值</string>
|
||||||
|
<string name="disable_horizontal_animation">禁用水平滚动动画</string>
|
||||||
|
<string name="enable_manga_gray">开启图片灰色</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1226,4 +1226,10 @@
|
|||||||
<string name="read_chapter_total">共 %d 章</string>
|
<string name="read_chapter_total">共 %d 章</string>
|
||||||
<string name="read_chapter_index">已读 %d 章</string>
|
<string name="read_chapter_index">已读 %d 章</string>
|
||||||
|
|
||||||
|
<string name="manga_epaper">墨水屏</string>
|
||||||
|
<string name="manga_epaper_stting">墨水屏设置</string>
|
||||||
|
<string name="manga_epaper_value">阈值</string>
|
||||||
|
<string name="disable_horizontal_animation">禁用水平滚动动画</string>
|
||||||
|
<string name="enable_manga_gray">开启图片灰色</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user