增加水平滚动 (#4760)

* 优化

* 页脚增加章节名称配置,增加返回提示加入书架

* 增加水平滚动
This commit is contained in:
lhjgege
2025-03-02 16:09:37 +08:00
committed by GitHub
parent 72dbab3d84
commit 3ea8eb67d2
14 changed files with 90 additions and 31 deletions
@@ -100,6 +100,7 @@ object PreferKey {
const val mangaFooterConfig = "mangaFooterConfig" const val mangaFooterConfig = "mangaFooterConfig"
const val singlePageScrolling = "singlePageScrolling" const val singlePageScrolling = "singlePageScrolling"
const val disableClickScroller = "disableClickScroller" const val disableClickScroller = "disableClickScroller"
const val enableMangaHorizontalScroller="enableMangaHorizontalScroller"
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"
@@ -651,5 +651,11 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
appCtx.putPrefString(PreferKey.mangaFooterConfig, value) appCtx.putPrefString(PreferKey.mangaFooterConfig, value)
} }
//漫画水平滚动
var enableMangaHorizontalScroller
get() = appCtx.getPrefBoolean(PreferKey.enableMangaHorizontalScroller, false)
set(value) {
appCtx.putPrefBoolean(PreferKey.enableMangaHorizontalScroller, value)
}
} }
@@ -3,6 +3,7 @@ package io.legado.app.model.recyclerView
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.view.Gravity
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
@@ -52,7 +53,7 @@ open class MangaVH<VB : ViewBinding>(val binding: VB, private val context: Conte
} }
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
fun loadImageWithRetry(imageUrl: String) { fun loadImageWithRetry(imageUrl: String, isHorizontal: Boolean) {
mFlProgress.isVisible = true mFlProgress.isVisible = true
mLoading.isVisible = true mLoading.isVisible = true
mRetry?.isGone = true mRetry?.isGone = true
@@ -102,8 +103,14 @@ open class MangaVH<VB : ViewBinding>(val binding: VB, private val context: Conte
isFirstResource: Boolean, isFirstResource: Boolean,
): Boolean { ): Boolean {
mFlProgress.isGone = true mFlProgress.isGone = true
itemView.updateLayoutParams<ViewGroup.LayoutParams> { if (!isHorizontal) {
height = WRAP_CONTENT itemView.updateLayoutParams<ViewGroup.LayoutParams> {
height = WRAP_CONTENT
}
} else {
mImage.updateLayoutParams<FrameLayout.LayoutParams> {
gravity = Gravity.CENTER
}
} }
return false return false
} }
@@ -73,7 +73,11 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, MangaViewModel>()
ReadManga.Callback, ChangeBookSourceDialog.CallBack, MangaMenu.CallBack { ReadManga.Callback, ChangeBookSourceDialog.CallBack, MangaMenu.CallBack {
private val mLayoutManager by lazy { private val mLayoutManager by lazy {
LinearLayoutManager(this@ReadMangaActivity) LinearLayoutManager(
this@ReadMangaActivity,
if (AppConfig.enableMangaHorizontalScroller) LinearLayoutManager.HORIZONTAL else LinearLayoutManager.VERTICAL,
false
)
} }
private val mAdapter: MangaAdapter by lazy { private val mAdapter: MangaAdapter by lazy {
MangaAdapter(this@ReadMangaActivity) MangaAdapter(this@ReadMangaActivity)
@@ -92,18 +96,8 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, MangaViewModel>()
) )
} }
private val mPagerSnapHelper: PagerSnapHelper by lazy { private var mPagerSnapHelper: PagerSnapHelper? = null
object : PagerSnapHelper() {
override fun calculateDistanceToFinalSnap(
layoutManager: RecyclerView.LayoutManager,
targetView: View
): IntArray {
val out = IntArray(2)
out[1] = targetView.top - binding.mRecyclerMange.paddingTop
return out
}
}
}
private var mDisableAutoScrollPage = false private var mDisableAutoScrollPage = false
private val mInitMangaAutoPageSpeed by lazy { private val mInitMangaAutoPageSpeed by lazy {
AppConfig.mangaAutoPageSpeed AppConfig.mangaAutoPageSpeed
@@ -197,6 +191,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, MangaViewModel>()
} }
private fun initRecyclerView() { private fun initRecyclerView() {
mAdapter.isHorizontal = AppConfig.enableMangaHorizontalScroller
binding.mRecyclerMange.run { binding.mRecyclerMange.run {
adapter = mAdapter adapter = mAdapter
itemAnimator = null itemAnimator = null
@@ -205,11 +200,14 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, MangaViewModel>()
mLayoutManager.initialPrefetchItemCount = 4 mLayoutManager.initialPrefetchItemCount = 4
mLayoutManager.isItemPrefetchEnabled = true mLayoutManager.isItemPrefetchEnabled = true
setItemViewCacheSize(AppConfig.preDownloadNum) setItemViewCacheSize(AppConfig.preDownloadNum)
singlePagerScroller(AppConfig.singlePageScrolling) singlePagerScroller(
AppConfig.singlePageScrolling,
AppConfig.enableMangaHorizontalScroller
)
disabledClickScroller(AppConfig.disableClickScroller) disabledClickScroller(AppConfig.disableClickScroller)
disableMangaScaling(AppConfig.disableMangaScaling) disableMangaScaling(AppConfig.disableMangaScaling)
setPreScrollListener { _, _, dy, position -> setPreScrollListener { _, dx, dy, position ->
if (dy > 0 && position + 2 > mAdapter.getCurrentList().size - 3) { if ((dy > 0 || dx > 0) && position + 2 > mAdapter.getCurrentList().size - 3) {
if (mAdapter.getCurrentList().last() is ReaderLoading) { if (mAdapter.getCurrentList().last() is ReaderLoading) {
val nextIndex = val nextIndex =
(mAdapter.getCurrentList().last() as ReaderLoading).mNextChapterIndex (mAdapter.getCurrentList().last() as ReaderLoading).mNextChapterIndex
@@ -319,7 +317,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, MangaViewModel>()
chapterPageCount: Int, chapterPageCount: Int,
chapterPos: Int, chapterPos: Int,
chapterCount: Int, chapterCount: Int,
chapterName: String chapterName: String,
) { ) {
mMangaFooterConfig.run { mMangaFooterConfig.run {
mLabelBuilder.clear() mLabelBuilder.clear()
@@ -490,7 +488,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, MangaViewModel>()
R.id.menu_scroller_page -> { R.id.menu_scroller_page -> {
item.isChecked = !item.isChecked item.isChecked = !item.isChecked
AppConfig.singlePageScrolling = item.isChecked AppConfig.singlePageScrolling = item.isChecked
singlePagerScroller(item.isChecked) singlePagerScroller(item.isChecked, AppConfig.enableMangaHorizontalScroller)
} }
R.id.menu_disable_manga_scaling -> { R.id.menu_disable_manga_scaling -> {
@@ -531,6 +529,19 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, MangaViewModel>()
R.id.menu_manga_footer_config -> { R.id.menu_manga_footer_config -> {
MangaFooterSettingDialog().show(supportFragmentManager, "mangaFooterSettingDialog") MangaFooterSettingDialog().show(supportFragmentManager, "mangaFooterSettingDialog")
} }
R.id.menu_enable_horizontal_scroller -> {
item.isChecked = !item.isChecked
AppConfig.enableMangaHorizontalScroller = item.isChecked
mLayoutManager.orientation =
if (item.isChecked) LinearLayoutManager.HORIZONTAL else LinearLayoutManager.VERTICAL
singlePagerScroller(AppConfig.singlePageScrolling, item.isChecked)
mAdapter.isHorizontal = item.isChecked
mAdapter.notifyItemRangeChanged(
ReadManga.durChapterPos.minus(2),
mAdapter.getCurrentList().size
)
}
} }
return super.onCompatOptionsItemSelected(item) return super.onCompatOptionsItemSelected(item)
} }
@@ -576,11 +587,26 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, MangaViewModel>()
binding.mRecyclerMange.addOnScrollListener(mRecyclerViewPreloader!!) binding.mRecyclerMange.addOnScrollListener(mRecyclerViewPreloader!!)
} }
private fun singlePagerScroller(value: Boolean) { private fun singlePagerScroller(enableSingleScroll: Boolean, enableHorizontalScroll: Boolean) {
if (value) { if (enableSingleScroll) {
mPagerSnapHelper.attachToRecyclerView(binding.mRecyclerMange) mPagerSnapHelper?.attachToRecyclerView(null)
mPagerSnapHelper = if (enableHorizontalScroll) {
PagerSnapHelper()
} else {
object : PagerSnapHelper() {
override fun calculateDistanceToFinalSnap(
layoutManager: RecyclerView.LayoutManager,
targetView: View,
): IntArray {
val out = IntArray(2)
out[1] = targetView.top - binding.mRecyclerMange.paddingTop
return out
}
}
}
mPagerSnapHelper?.attachToRecyclerView(binding.mRecyclerMange)
} else { } else {
mPagerSnapHelper.attachToRecyclerView(null) mPagerSnapHelper?.attachToRecyclerView(null)
} }
} }
@@ -594,6 +620,8 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, MangaViewModel>()
menu.findItem(R.id.menu_disable_click_scroller).isChecked = AppConfig.disableClickScroller menu.findItem(R.id.menu_disable_click_scroller).isChecked = AppConfig.disableClickScroller
menu.findItem(R.id.menu_manga_auto_page_speed).title = menu.findItem(R.id.menu_manga_auto_page_speed).title =
getString(R.string.manga_auto_page_speed, mMangaAutoPageSpeed) getString(R.string.manga_auto_page_speed, mMangaAutoPageSpeed)
menu.findItem(R.id.menu_enable_horizontal_scroller).isChecked =
AppConfig.enableMangaHorizontalScroller
} }
private fun disableMangaScaling(disable: Boolean) { private fun disableMangaScaling(disable: Boolean) {
@@ -662,7 +690,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, MangaViewModel>()
min: Int, min: Int,
title: String, title: String,
initValue: Int, initValue: Int,
callback: (Int) -> Unit callback: (Int) -> Unit,
) { ) {
NumberPickerDialog(this) NumberPickerDialog(this)
.setTitle(title) .setTitle(title)
@@ -22,8 +22,8 @@ import io.legado.app.databinding.BookComicRvBinding
import io.legado.app.help.glide.progress.ProgressManager import io.legado.app.help.glide.progress.ProgressManager
import io.legado.app.model.BookCover import io.legado.app.model.BookCover
import io.legado.app.model.ReadManga import io.legado.app.model.ReadManga
import io.legado.app.model.recyclerView.MangaVH
import io.legado.app.model.recyclerView.MangaContent import io.legado.app.model.recyclerView.MangaContent
import io.legado.app.model.recyclerView.MangaVH
import io.legado.app.model.recyclerView.ReaderLoading import io.legado.app.model.recyclerView.ReaderLoading
import io.legado.app.utils.getCompatDrawable import io.legado.app.utils.getCompatDrawable
import java.util.Collections import java.util.Collections
@@ -37,6 +37,8 @@ class MangaAdapter(private val context: Context) :
private const val CONTENT_VIEW = 1 private const val CONTENT_VIEW = 1
} }
var isHorizontal = false
private val mDiffCallback: DiffUtil.ItemCallback<Any> = object : DiffUtil.ItemCallback<Any>() { private val mDiffCallback: DiffUtil.ItemCallback<Any> = object : DiffUtil.ItemCallback<Any>() {
override fun areItemsTheSame(oldItem: Any, newItem: Any): Boolean { override fun areItemsTheSame(oldItem: Any, newItem: Any): Boolean {
return if (oldItem is ReaderLoading && newItem is ReaderLoading) { return if (oldItem is ReaderLoading && newItem is ReaderLoading) {
@@ -89,13 +91,13 @@ class MangaAdapter(private val context: Context) :
binding.retry.setOnClickListener { binding.retry.setOnClickListener {
val item = mDiffer.currentList[layoutPosition] val item = mDiffer.currentList[layoutPosition]
if (item is MangaContent) { if (item is MangaContent) {
loadImageWithRetry(item.mImageUrl) loadImageWithRetry(item.mImageUrl, isHorizontal)
} }
} }
} }
fun onBind(item: MangaContent) { fun onBind(item: MangaContent) {
loadImageWithRetry(item.mImageUrl) loadImageWithRetry(item.mImageUrl, isHorizontal)
} }
} }
+9 -2
View File
@@ -54,12 +54,19 @@
<item <item
android:id="@+id/menu_manga_auto_page_speed" android:id="@+id/menu_manga_auto_page_speed"
android:visible="false"
android:title="@string/manga_auto_page_speed" android:title="@string/manga_auto_page_speed"
android:visible="false"
app:showAsAction="never" />
<item
android:id="@+id/menu_enable_horizontal_scroller"
android:checkable="true"
android:checked="false"
android:title="@string/enable_manga_horizontal_scroller"
app:showAsAction="never" /> 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"
app:showAsAction="never"/> app:showAsAction="never" />
</menu> </menu>
@@ -1205,4 +1205,5 @@
<string name="manga_header_footer">页脚</string> <string name="manga_header_footer">页脚</string>
<string name="manga_radio_left">靠左</string> <string name="manga_radio_left">靠左</string>
<string name="manga_radio_center">居中</string> <string name="manga_radio_center">居中</string>
<string name="enable_manga_horizontal_scroller">水平滚动</string>
</resources> </resources>
@@ -1208,4 +1208,5 @@
<string name="manga_header_footer">页脚</string> <string name="manga_header_footer">页脚</string>
<string name="manga_radio_left">靠左</string> <string name="manga_radio_left">靠左</string>
<string name="manga_radio_center">居中</string> <string name="manga_radio_center">居中</string>
<string name="enable_manga_horizontal_scroller">水平滚动</string>
</resources> </resources>
@@ -1208,4 +1208,5 @@
<string name="manga_header_footer">页脚</string> <string name="manga_header_footer">页脚</string>
<string name="manga_radio_left">靠左</string> <string name="manga_radio_left">靠左</string>
<string name="manga_radio_center">居中</string> <string name="manga_radio_center">居中</string>
<string name="enable_manga_horizontal_scroller">水平滚动</string>
</resources> </resources>
+1
View File
@@ -1204,4 +1204,5 @@ Còn </string>
<string name="manga_header_footer">页脚</string> <string name="manga_header_footer">页脚</string>
<string name="manga_radio_left">靠左</string> <string name="manga_radio_left">靠左</string>
<string name="manga_radio_center">居中</string> <string name="manga_radio_center">居中</string>
<string name="enable_manga_horizontal_scroller">水平滚动</string>
</resources> </resources>
@@ -1205,4 +1205,5 @@
<string name="manga_header_footer">页脚</string> <string name="manga_header_footer">页脚</string>
<string name="manga_radio_left">靠左</string> <string name="manga_radio_left">靠左</string>
<string name="manga_radio_center">居中</string> <string name="manga_radio_center">居中</string>
<string name="enable_manga_horizontal_scroller">水平滚动</string>
</resources> </resources>
@@ -1207,4 +1207,5 @@
<string name="manga_header_footer">页脚</string> <string name="manga_header_footer">页脚</string>
<string name="manga_radio_left">靠左</string> <string name="manga_radio_left">靠左</string>
<string name="manga_radio_center">居中</string> <string name="manga_radio_center">居中</string>
<string name="enable_manga_horizontal_scroller">水平滚动</string>
</resources> </resources>
+1
View File
@@ -1207,4 +1207,5 @@
<string name="manga_header_footer">页脚</string> <string name="manga_header_footer">页脚</string>
<string name="manga_radio_left">靠左</string> <string name="manga_radio_left">靠左</string>
<string name="manga_radio_center">居中</string> <string name="manga_radio_center">居中</string>
<string name="enable_manga_horizontal_scroller">水平滚动</string>
</resources> </resources>
+1
View File
@@ -1208,4 +1208,5 @@
<string name="manga_header_footer">页脚</string> <string name="manga_header_footer">页脚</string>
<string name="manga_radio_left">靠左</string> <string name="manga_radio_left">靠左</string>
<string name="manga_radio_center">居中</string> <string name="manga_radio_center">居中</string>
<string name="enable_manga_horizontal_scroller">水平滚动</string>
</resources> </resources>