mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
优化 (#4713)
* 升级RecyclerView适配自适应刷新率 * 减小菜单点击区域 * ... * 修复显示章节位置问题,修复顶部间距问题 * 显示漫画名称 * ... * ... * 漫画缩放移植到右上角 增加预加载数量设置 增加单页滚动
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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,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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user