Просмотр исходного кода

优化 (#4713)

* 升级RecyclerView适配自适应刷新率

* 减小菜单点击区域

* ...

* 修复显示章节位置问题,修复顶部间距问题

* 显示漫画名称

* ...

* ...

* 漫画缩放移植到右上角
增加预加载数量设置
增加单页滚动
lhjgege 1 год назад
Родитель
Сommit
90180f0cb6

+ 2 - 0
app/src/main/java/io/legado/app/constant/PreferKey.kt

@@ -95,6 +95,8 @@ object PreferKey {
     const val bitmapCacheSize = "bitmapCacheSize"
     const val imageRetainNum = "imageRetainNum"
     const val preDownloadNum = "preDownloadNum"
+    const val preMangaDownloadNum = "preMangaDownloadNum"
+    const val singlePageScrolling="singlePageScrolling"
     const val autoRefresh = "auto_refresh"
     const val defaultToRead = "defaultToRead"
     const val exportCharset = "exportCharset"

+ 18 - 1
app/src/main/java/io/legado/app/help/config/AppConfig.kt

@@ -610,7 +610,24 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
         get() = appCtx.getPrefBoolean(PreferKey.showMangaUi, true)
 
     //禁用漫画缩放
-    val disableMangaScaling: Boolean
+    var disableMangaScaling: Boolean
         get() = appCtx.getPrefBoolean(PreferKey.disableMangaScaling, true)
+        set(value) {
+            appCtx.putPrefBoolean(PreferKey.disableMangaScaling, value)
+        }
+
+    //漫画预加载数量
+    var preMangaDownloadNum
+        get() = appCtx.getPrefInt(PreferKey.preMangaDownloadNum, 10)
+        set(value) {
+            appCtx.putPrefInt(PreferKey.preMangaDownloadNum, value)
+        }
+
+    //单页滚动
+    var singlePageScrolling
+        get() = appCtx.getPrefBoolean(PreferKey.singlePageScrolling, false)
+        set(value) {
+            appCtx.putPrefBoolean(PreferKey.singlePageScrolling, value)
+        }
 }
 

+ 82 - 11
app/src/main/java/io/legado/app/ui/book/manga/ReadMangaActivity.kt

@@ -1,5 +1,6 @@
 package io.legado.app.ui.book.manga
 
+import android.annotation.SuppressLint
 import android.content.Intent
 import android.os.Bundle
 import android.os.Looper
@@ -14,6 +15,7 @@ import androidx.core.view.isGone
 import androidx.core.view.isVisible
 import androidx.core.view.updateLayoutParams
 import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.PagerSnapHelper
 import com.bumptech.glide.Glide
 import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
 import com.bumptech.glide.request.target.Target.SIZE_ORIGINAL
@@ -42,6 +44,7 @@ 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.number.NumberPickerDialog
 import io.legado.app.ui.widget.recycler.LoadMoreView
 import io.legado.app.utils.NetworkUtils
 import io.legado.app.utils.StartActivityContract
@@ -64,17 +67,29 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
     private val mAdapter: MangaAdapter by lazy {
         MangaAdapter(this@ReadMangaActivity)
     }
+    private val mPreDownloadNum by lazy {
+        AppConfig.preMangaDownloadNum
+    }
+    private val mSinglePageScroller by lazy {
+        AppConfig.singlePageScrolling
+    }
+
+    private val mDisableMangaScaling by lazy {
+        AppConfig.disableMangaScaling
+    }
+
     private val mSizeProvider by lazy {
         FixedPreloadSizeProvider<Any>(
-            this@ReadMangaActivity.resources.displayMetrics.widthPixels,
-            SIZE_ORIGINAL
+            this@ReadMangaActivity.resources.displayMetrics.widthPixels, SIZE_ORIGINAL
         )
     }
 
-    private val mRecyclerViewPreloader by lazy {
-        RecyclerViewPreloader(Glide.with(this), mAdapter, mSizeProvider, 10)
+    private val mPagerSnapHelper: PagerSnapHelper by lazy {
+        PagerSnapHelper()
     }
 
+    private var mRecyclerViewPreloader: RecyclerViewPreloader<Any>? = null
+
     private val networkChangedListener by lazy {
         NetworkChangedListener(this)
     }
@@ -95,13 +110,12 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
     }
 
     //打开目录返回选择章节返回结果
-    private val tocActivity =
-        registerForActivityResult(TocActivityResult()) {
-            it?.let {
-                binding.flLoading.isVisible = true
-                viewModel.openChapter(it.first, it.second)
-            }
+    private val tocActivity = registerForActivityResult(TocActivityResult()) {
+        it?.let {
+            binding.flLoading.isVisible = true
+            viewModel.openChapter(it.first, it.second)
         }
+    }
     private val bookInfoActivity =
         registerForActivityResult(StartActivityContract(BookInfoActivity::class.java)) {
             if (it.resultCode == RESULT_OK) {
@@ -122,6 +136,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
             }
         }
         ReadManga.register(this)
+        disableMangaScaling(mDisableMangaScaling)
         binding.mRecyclerMange.run {
             adapter = mAdapter
             itemAnimator = null
@@ -130,6 +145,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
             mLayoutManager.initialPrefetchItemCount = 4
             mLayoutManager.isItemPrefetchEnabled = true
             setItemViewCacheSize(AppConfig.preDownloadNum)
+            singlePagerScroller(mSinglePageScroller)
             setPreScrollListener { _, _, dy, position ->
                 if (dy > 0 && position + 2 > mAdapter.getCurrentList().size - 3) {
                     if (mAdapter.getCurrentList().last() is ReaderLoading) {
@@ -162,7 +178,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
 
                 }
             }
-            addOnScrollListener(mRecyclerViewPreloader)
+            addRecyclerViewPreloader(mPreDownloadNum)
             onToucheMiddle {
                 if (!binding.mangaMenu.isVisible) {
                     binding.mangaMenu.runMenuIn()
@@ -347,14 +363,17 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
     }
 
 
+    @SuppressLint("StringFormatMatches")
     override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
         menuInflater.inflate(R.menu.book_manga, menu)
+        upMenu(menu)
         return super.onCompatCreateOptionsMenu(menu)
     }
 
     /**
      * 菜单
      */
+    @SuppressLint("StringFormatMatches")
     override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
         when (item.itemId) {
             R.id.menu_change_source -> {
@@ -369,6 +388,27 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
                     tocActivity.launch(it.bookUrl)
                 }
             }
+
+            R.id.menu_pre_manga_number -> {
+                NumberPickerDialog(this).setTitle(getString(R.string.pre_download))
+                    .setMaxValue(9999).setMinValue(0).setValue(AppConfig.preMangaDownloadNum).show {
+                        AppConfig.preMangaDownloadNum = it
+                        item.setTitle(getString(R.string.pre_download_m, it))
+                        addRecyclerViewPreloader(it)
+                    }
+            }
+
+            R.id.menu_scroller_page -> {
+                item.isChecked = !item.isChecked
+                AppConfig.singlePageScrolling = item.isChecked
+                singlePagerScroller(item.isChecked)
+            }
+
+            R.id.menu_disable_manga_scaling -> {
+                item.isChecked = !item.isChecked
+                AppConfig.disableMangaScaling = item.isChecked
+                disableMangaScaling(item.isChecked)
+            }
         }
         return super.onCompatOptionsItemSelected(item)
     }
@@ -405,4 +445,35 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
         return super.dispatchKeyEvent(event)
     }
 
+    private fun addRecyclerViewPreloader(maxPreload: Int) {
+        if (mRecyclerViewPreloader != null) {
+            binding.mRecyclerMange.removeOnScrollListener(mRecyclerViewPreloader!!)
+        }
+        mRecyclerViewPreloader = RecyclerViewPreloader(
+            Glide.with(this), mAdapter, mSizeProvider, maxPreload
+        )
+        binding.mRecyclerMange.addOnScrollListener(mRecyclerViewPreloader!!)
+    }
+
+    private fun singlePagerScroller(value: Boolean) {
+        if (value) {
+            mPagerSnapHelper.attachToRecyclerView(binding.mRecyclerMange)
+        } else {
+            mPagerSnapHelper.attachToRecyclerView(null)
+        }
+    }
+
+    @SuppressLint("StringFormatMatches")
+    private fun upMenu(menu: Menu) {
+        menu.findItem(R.id.menu_pre_manga_number)
+            .setTitle(getString(R.string.pre_download_m, mPreDownloadNum))
+        menu.findItem(R.id.menu_scroller_page).isChecked = mSinglePageScroller
+        menu.findItem(R.id.menu_disable_manga_scaling).isChecked = mDisableMangaScaling
+    }
+
+    private fun disableMangaScaling(disable: Boolean) {
+        binding.webtoonFrame.disableMangaScaling = disable
+        binding.mRecyclerMange.disableMangaScaling = disable
+    }
+
 }

+ 3 - 2
app/src/main/java/io/legado/app/ui/book/manga/rv/WebtoonFrame.kt

@@ -7,7 +7,6 @@ import android.view.GestureDetector
 import android.view.MotionEvent
 import android.view.ScaleGestureDetector
 import android.widget.FrameLayout
-import io.legado.app.help.config.AppConfig
 
 class WebtoonFrame : FrameLayout {
 
@@ -29,11 +28,13 @@ class WebtoonFrame : FrameLayout {
             scaleDetector.isQuickScaleEnabled = value
         }
 
+    var disableMangaScaling = false
+
     private val recycler: WebtoonRecyclerView?
         get() = getChildAt(0) as? WebtoonRecyclerView
 
     override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
-        if (!AppConfig.disableMangaScaling) {
+        if (!disableMangaScaling) {
             scaleDetector.onTouchEvent(ev)
             flingDetector.onTouchEvent(ev)
             val recyclerRect = Rect()

+ 29 - 10
app/src/main/java/io/legado/app/ui/book/manga/rv/WebtoonRecyclerView.kt

@@ -12,7 +12,6 @@ import android.view.animation.DecelerateInterpolator
 import androidx.core.animation.doOnEnd
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import io.legado.app.help.config.AppConfig
 import io.legado.app.utils.findCenterViewPosition
 import kotlin.math.abs
 
@@ -40,17 +39,23 @@ class WebtoonRecyclerView @JvmOverloads constructor(
     private val listener = GestureListener()
     private val detector = Detector()
     private val mcRect = RectF()
-    private var mToucheMiddle: (() -> Unit)? = null
+    private val blRect = RectF()
+    private val brRect = RectF()
 
     //起始点
     private var startX: Float = 0f
     private var startY: Float = 0f
-
     var doubleTapZoom = true
-
     var tapListener: ((MotionEvent) -> Unit)? = null
     var longTapListener: ((MotionEvent) -> Boolean)? = null
+    var disableMangaScaling = false
+
+    private var mToucheMiddle: (() -> Unit)? = null
     fun onToucheMiddle(init: () -> Unit) = apply { this.mToucheMiddle = init }
+    private var mNextPage: (() -> Unit)? = null
+    fun onNextPage(init: () -> Unit) = apply { this.mNextPage = init }
+    private var mPrevPage: (() -> Unit)? = null
+    fun onPrevPage(init: () -> Unit) = apply { this.mPrevPage = init }
 
     override fun onMeasure(widthSpec: Int, heightSpec: Int) {
         halfWidth = MeasureSpec.getSize(widthSpec) / 2
@@ -102,7 +107,9 @@ class WebtoonRecyclerView @JvmOverloads constructor(
 
     override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
         super.onSizeChanged(w, h, oldw, oldh)
-        mcRect.set(width * 0.33f, height * 0.33f, width * 0.66f, height * 0.66f)
+        mcRect.set(width * 0.33f, height * 0.33f, width * 0.66f, height * 0.46f)
+        blRect.set(0f, height * 0.66f, width * 0.33f, height.toFloat())
+        brRect.set(width * 0.66f, height * 0.66f, width.toFloat(), height.toFloat())
     }
 
     private fun getPositionX(positionX: Float): Float {
@@ -240,10 +247,23 @@ class WebtoonRecyclerView @JvmOverloads constructor(
     inner class GestureListener : GestureDetectorWithLongTap.Listener() {
 
         override fun onSingleTapConfirmed(ev: MotionEvent): Boolean {
-            if (mcRect.contains(startX, startY)) {
-                mToucheMiddle?.invoke()
-            } else {
-                tapListener?.invoke(ev)
+            when {
+                mcRect.contains(startX, startY) -> {
+                    mToucheMiddle?.invoke()
+                }
+
+                blRect.contains(startX, startY) -> {
+                    mPrevPage?.invoke()
+                }
+
+                brRect.contains(startX, startY) -> {
+                    mNextPage?.invoke()
+                }
+
+                else -> {
+                    tapListener?.invoke(ev)
+
+                }
             }
             return false
         }
@@ -282,7 +302,6 @@ class WebtoonRecyclerView @JvmOverloads constructor(
         private var isZoomDragging = false
         var isDoubleTapping = false
         var isQuickScaling = false
-        val disableMangaScaling = AppConfig.disableMangaScaling
         override fun onTouchEvent(ev: MotionEvent): Boolean {
             val action = ev.actionMasked
             val actionIndex = ev.actionIndex

+ 1 - 0
app/src/main/res/layout/activity_mange.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <io.legado.app.ui.book.manga.rv.WebtoonFrame xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/webtoonFrame"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"

+ 19 - 0
app/src/main/res/menu/book_manga.xml

@@ -18,4 +18,23 @@
             app:showAsAction="always" />
 
     </group>
+
+    <item
+        android:id="@+id/menu_pre_manga_number"
+        android:title="@string/pre_download"
+        app:showAsAction="never" />
+
+    <item
+        android:id="@+id/menu_scroller_page"
+        android:checkable="true"
+        android:checked="false"
+        android:title="@string/single_page_scroller"
+        app:showAsAction="never" />
+
+    <item
+        android:id="@+id/menu_disable_manga_scaling"
+        android:checkable="true"
+        android:checked="false"
+        android:title="@string/disable_manga_scaling"
+        app:showAsAction="never" />
 </menu>

+ 2 - 0
app/src/main/res/values-es-rES/strings.xml

@@ -820,6 +820,8 @@
     <string name="export_bookshelf">Exportar lista de libros</string>
     <string name="import_bookshelf">Importar lista de libros</string>
     <string name="pre_download">Descarga anterior</string>
+    <string name="pre_download_m">预下载%s页</string>
+    <string name="single_page_scroller">单页滚动</string>
     <string name="pre_download_s">Descargue %s capítulos antes</string>
     <string name="is_enabled">Está habilitado</string>
     <string name="background_image">Imagen de fondo</string>

+ 2 - 0
app/src/main/res/values-ja-rJP/strings.xml

@@ -823,6 +823,8 @@
     <string name="export_bookshelf">Export the list of books</string>
     <string name="import_bookshelf">Import the list of books</string>
     <string name="pre_download">Download in advance</string>
+    <string name="pre_download_m">预下载%s页</string>
+    <string name="single_page_scroller">单页滚动</string>
     <string name="pre_download_s">Download %s chapters in advance</string>
     <string name="is_enabled">Is enabled</string>
     <string name="background_image">Background image</string>

+ 2 - 0
app/src/main/res/values-pt-rBR/strings.xml

@@ -821,6 +821,8 @@
     <string name="export_bookshelf">Exportar a lista de livros</string>
     <string name="import_bookshelf">Importar a lista de livros</string>
     <string name="pre_download">Baixar antecipadamente</string>
+    <string name="pre_download_m">预下载%s页</string>
+    <string name="single_page_scroller">单页滚动</string>
     <string name="pre_download_s">Baixar %s capítulos antecipadamente</string>
     <string name="is_enabled">Está ativado</string>
     <string name="background_image">Imagem de fundo</string>

+ 2 - 0
app/src/main/res/values-vi/strings.xml

@@ -822,6 +822,8 @@ Còn </string>
     <string name="export_bookshelf">Xuất bookshelf</string>
     <string name="import_bookshelf">Nhập bookshelf</string>
     <string name="pre_download">Tải xuống trước</string>
+    <string name="pre_download_m">预下载%s页</string>
+    <string name="single_page_scroller">单页滚动</string>
     <string name="pre_download_s">Tải xuống trước %s chương</string>
     <string name="is_enabled">Đã bật</string>
     <string name="background_image">Ảnh nền</string>

+ 2 - 0
app/src/main/res/values-zh-rHK/strings.xml

@@ -821,6 +821,8 @@
     <string name="export_bookshelf">導出書單</string>
     <string name="import_bookshelf">導入書單</string>
     <string name="pre_download">預下載</string>
+    <string name="pre_download_m">預下載%s页</string>
+    <string name="single_page_scroller">单页滚动</string>
     <string name="pre_download_s">預先下載%s章正文</string>
     <string name="is_enabled">係咪啟用</string>
     <string name="background_image">背景圖片</string>

+ 2 - 0
app/src/main/res/values-zh-rTW/strings.xml

@@ -824,6 +824,8 @@
     <string name="export_bookshelf">匯出書單</string>
     <string name="import_bookshelf">匯入書單</string>
     <string name="pre_download">預下載</string>
+    <string name="pre_download_m">预下载%s页</string>
+    <string name="single_page_scroller">单页滚动</string>
     <string name="pre_download_s">預先下載%s章正文</string>
     <string name="is_enabled">是否啟用</string>
     <string name="background_image">背景圖片</string>

+ 2 - 0
app/src/main/res/values-zh/strings.xml

@@ -827,6 +827,8 @@
     <string name="export_bookshelf">导出书单</string>
     <string name="import_bookshelf">导入书单</string>
     <string name="pre_download">预下载</string>
+    <string name="single_page_scroller">单页滚动</string>
+    <string name="pre_download_m">预下载%s页</string>
     <string name="pre_download_s">预先下载 %s 章正文</string>
     <string name="is_enabled">是否启用</string>
     <string name="background_image">背景图片</string>

+ 2 - 0
app/src/main/res/values/strings.xml

@@ -828,6 +828,8 @@
     <string name="export_bookshelf">Export the list of books</string>
     <string name="import_bookshelf">Import the list of books</string>
     <string name="pre_download">Download in advance</string>
+    <string name="pre_download_m">Pre-download %s pages</string>
+    <string name="single_page_scroller">Single Page Scroller</string>
     <string name="pre_download_s">Download %s chapters in advance</string>
     <string name="is_enabled">Is enabled</string>
     <string name="background_image">Background image</string>

+ 0 - 6
app/src/main/res/xml/pref_config_other.xml

@@ -174,12 +174,6 @@
             android:title="@string/show_mange_ui"
             app:iconSpaceReserved="false" />
 
-        <io.legado.app.lib.prefs.SwitchPreference
-            android:defaultValue="true"
-            android:key="disableMangaScaling"
-            android:title="@string/disable_manga_scaling"
-            app:iconSpaceReserved="false" />
-
         <io.legado.app.lib.prefs.Preference
             android:key="webPort"
             android:title="@string/web_port_title"