From 17e16958a3beb6d53cccd8fc8aeb540e8ce4bde1 Mon Sep 17 00:00:00 2001 From: HapeLee <1321903405@qq.com> Date: Wed, 3 Sep 2025 04:12:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=BC=AB=E7=94=BB=E5=8F=AF?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kazusa/ui/book/manga/ReadMangaActivity.kt | 72 +++++++++---------- .../ui/book/manga/ReadMangaViewModel.kt | 41 +++++++++++ ...llModeDialog.kt => MangaAutoReadDialog.kt} | 6 +- .../manga/config/MangaFooterSettingDialog.kt | 11 ++- .../{config => entities}/MangaFooterConfig.kt | 4 +- .../book/manga/recyclerview/WebtoonFrame.kt | 33 ++++++--- 6 files changed, 116 insertions(+), 51 deletions(-) rename app/src/main/java/io/legato/kazusa/ui/book/manga/config/{MangaScrollModeDialog.kt => MangaAutoReadDialog.kt} (84%) rename app/src/main/java/io/legato/kazusa/ui/book/manga/{config => entities}/MangaFooterConfig.kt (77%) diff --git a/app/src/main/java/io/legato/kazusa/ui/book/manga/ReadMangaActivity.kt b/app/src/main/java/io/legato/kazusa/ui/book/manga/ReadMangaActivity.kt index 70de9b730..011cfd13e 100644 --- a/app/src/main/java/io/legato/kazusa/ui/book/manga/ReadMangaActivity.kt +++ b/app/src/main/java/io/legato/kazusa/ui/book/manga/ReadMangaActivity.kt @@ -39,19 +39,21 @@ import io.legato.kazusa.help.book.isImage import io.legato.kazusa.help.book.removeType import io.legato.kazusa.help.config.AppConfig import io.legato.kazusa.help.storage.Backup +import io.legato.kazusa.lib.dialogs.SelectItem import io.legato.kazusa.lib.dialogs.alert +import io.legato.kazusa.lib.dialogs.selector import io.legato.kazusa.model.ReadManga import io.legato.kazusa.receiver.NetworkChangedListener import io.legato.kazusa.ui.book.changesource.ChangeBookSourceDialog import io.legato.kazusa.ui.book.info.BookInfoActivity +import io.legato.kazusa.ui.book.manga.config.MangaAutoReadDialog import io.legato.kazusa.ui.book.manga.config.MangaClickActionConfigDialog 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.MangaFooterConfig import io.legato.kazusa.ui.book.manga.config.MangaFooterSettingDialog import io.legato.kazusa.ui.book.manga.config.MangaScrollMode -import io.legato.kazusa.ui.book.manga.config.MangaScrollModeDialog import io.legato.kazusa.ui.book.manga.entities.BaseMangaPage +import io.legato.kazusa.ui.book.manga.entities.MangaFooterConfig import io.legato.kazusa.ui.book.manga.entities.MangaPage import io.legato.kazusa.ui.book.manga.recyclerview.MangaAdapter import io.legato.kazusa.ui.book.manga.recyclerview.MangaLayoutManager @@ -85,7 +87,7 @@ import kotlin.math.ceil class ReadMangaActivity : VMBaseActivity(), ReadManga.Callback, ChangeBookSourceDialog.CallBack, MangaMenu.CallBack, MangaColorFilterDialog.Callback, ScrollTimer.ScrollCallback, MangaFooterSettingDialog.Callback, - MangaScrollModeDialog.Callback { + MangaAutoReadDialog.Callback { private val mLayoutManager by lazy { MangaLayoutManager(this) @@ -161,21 +163,16 @@ class ReadMangaActivity : VMBaseActivity + selector( + arrayListOf( + SelectItem("保存", "save"), + SelectItem("分享", "share") + ) + ) { _, option, _ -> + when (option.value) { + "save" -> viewModel.saveImageToGallery(item.mImageUrl) + // "share" -> shareImage(item.mImageUrl) + } + } + } + } + + } override fun onNewIntent(intent: Intent) { @@ -585,7 +602,7 @@ class ReadMangaActivity : VMBaseActivity().applicationContext) + .asBitmap() + .load(url) + .submit() + .get() + val baos = ByteArrayOutputStream() + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos) + baos.toByteArray() + } + + val context = getApplication().applicationContext + val success = ImageSaveUtils.saveImageToGallery( + context, + byteArray, + folderName = folderName + ) + + if (success) { + context.toastOnUi("图片已保存到相册") + } else { + context.toastOnUi("保存失败") + } + } catch (e: Exception) { + context.toastOnUi("保存出错: ${e.localizedMessage}") + } + } + } + fun updateReadConfig(update: ReadConfig.() -> Unit) { val book = ReadManga.book ?: return diff --git a/app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaScrollModeDialog.kt b/app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaAutoReadDialog.kt similarity index 84% rename from app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaScrollModeDialog.kt rename to app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaAutoReadDialog.kt index f395e8261..cb736b824 100644 --- a/app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaScrollModeDialog.kt +++ b/app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaAutoReadDialog.kt @@ -4,13 +4,13 @@ import android.os.Bundle import android.view.View import io.legato.kazusa.R import io.legato.kazusa.base.BaseBottomSheetDialogFragment -import io.legato.kazusa.databinding.DialogMangaScrollModeBinding +import io.legato.kazusa.databinding.DialogMangaAutoReadBinding import io.legato.kazusa.help.config.AppConfig import io.legato.kazusa.utils.viewbindingdelegate.viewBinding -class MangaScrollModeDialog : BaseBottomSheetDialogFragment(R.layout.dialog_manga_scroll_mode) { +class MangaAutoReadDialog : BaseBottomSheetDialogFragment(R.layout.dialog_manga_auto_read) { - private val binding by viewBinding(DialogMangaScrollModeBinding::bind) + private val binding by viewBinding(DialogMangaAutoReadBinding::bind) var initialAutoPageEnabled: Boolean = false diff --git a/app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaFooterSettingDialog.kt b/app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaFooterSettingDialog.kt index e169f3a86..b5e9b21c3 100644 --- a/app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaFooterSettingDialog.kt +++ b/app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaFooterSettingDialog.kt @@ -4,12 +4,15 @@ import android.content.DialogInterface import android.os.Bundle import android.view.Gravity import android.view.View +import androidx.core.view.isVisible +import androidx.transition.TransitionManager import com.google.android.material.chip.Chip import io.legato.kazusa.R import io.legato.kazusa.base.BaseBottomSheetDialogFragment import io.legato.kazusa.constant.EventBus import io.legato.kazusa.databinding.DialogMangaFooterSettingBinding import io.legato.kazusa.help.config.AppConfig +import io.legato.kazusa.ui.book.manga.entities.MangaFooterConfig import io.legato.kazusa.ui.widget.ReaderInfoBarView import io.legato.kazusa.utils.GSON import io.legato.kazusa.utils.fromJsonObject @@ -46,10 +49,17 @@ class MangaFooterSettingDialog : setOnClickListener { callback?.onScrollModeChanged(mode) + TransitionManager.beginDelayedTransition(binding.rootView) + binding.llWebtoon.isVisible = mode == MangaScrollMode.WEBTOON || + mode == MangaScrollMode.WEBTOON_WITH_GAP } }) } + binding.llWebtoon.isVisible = initialScrollMode == MangaScrollMode.WEBTOON || + initialScrollMode == MangaScrollMode.WEBTOON_WITH_GAP + + binding.scvPadding.apply { valueFormat = { "$it %" } progress = initialWebtoonSidePadding @@ -200,7 +210,6 @@ class MangaFooterSettingDialog : } private fun updateChapterText() { - if (config.hideFooter) { binding.tvChapter.visibility = View.INVISIBLE return diff --git a/app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaFooterConfig.kt b/app/src/main/java/io/legato/kazusa/ui/book/manga/entities/MangaFooterConfig.kt similarity index 77% rename from app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaFooterConfig.kt rename to app/src/main/java/io/legato/kazusa/ui/book/manga/entities/MangaFooterConfig.kt index e26ce1ab6..da2132bd2 100644 --- a/app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaFooterConfig.kt +++ b/app/src/main/java/io/legato/kazusa/ui/book/manga/entities/MangaFooterConfig.kt @@ -1,4 +1,4 @@ -package io.legato.kazusa.ui.book.manga.config +package io.legato.kazusa.ui.book.manga.entities import androidx.annotation.Keep import io.legato.kazusa.ui.widget.ReaderInfoBarView @@ -11,7 +11,7 @@ data class MangaFooterConfig( var hidePageNumber: Boolean = false, var hideProgressRatioLabel: Boolean = false, var hideProgressRatio: Boolean = false, - var footerOrientation: Int = ReaderInfoBarView.ALIGN_LEFT,//默认靠左 + var footerOrientation: Int = ReaderInfoBarView.Companion.ALIGN_LEFT,//默认靠左 var hideFooter: Boolean = false, var hideChapterName:Boolean=false, ) \ No newline at end of file diff --git a/app/src/main/java/io/legato/kazusa/ui/book/manga/recyclerview/WebtoonFrame.kt b/app/src/main/java/io/legato/kazusa/ui/book/manga/recyclerview/WebtoonFrame.kt index 67e550c92..f62656667 100644 --- a/app/src/main/java/io/legato/kazusa/ui/book/manga/recyclerview/WebtoonFrame.kt +++ b/app/src/main/java/io/legato/kazusa/ui/book/manga/recyclerview/WebtoonFrame.kt @@ -8,7 +8,9 @@ import android.view.GestureDetector import android.view.MotionEvent import android.view.ScaleGestureDetector import android.widget.FrameLayout +import androidx.recyclerview.widget.RecyclerView import io.legato.kazusa.help.config.AppConfig +import io.legato.kazusa.utils.findCenterViewPosition class WebtoonFrame : FrameLayout { @@ -20,6 +22,9 @@ class WebtoonFrame : FrameLayout { defStyle ) + /** 长按回调,返回手指坐标 */ + var longPressListener: ((centerPosition: Int) -> Unit)? = null + private val scaleDetector = ScaleGestureDetector(context, ScaleListener()) private val flingDetector = GestureDetector(context, FlingListener()) private val regionRects = mutableMapOf() @@ -37,9 +42,22 @@ class WebtoonFrame : FrameLayout { get() = getChildAt(0) as? WebtoonRecyclerView var disabledClickScroll = false - var actionHandler: ClickActionHandler? = null + private val gestureDetector = + GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() { + override fun onLongPress(e: MotionEvent) { + recycler?.let { + val centerPos = it.findCenterViewPosition() + if (centerPos != RecyclerView.NO_POSITION) { + longPressListener?.invoke(centerPos) + } + } + } + + override fun onDown(e: MotionEvent): Boolean = true + }) + override fun onAttachedToWindow() { super.onAttachedToWindow() recycler?.tapListener = tapListener@{ ev -> @@ -63,7 +81,6 @@ class WebtoonFrame : FrameLayout { performClickAction(action) } - } override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { @@ -84,8 +101,9 @@ class WebtoonFrame : FrameLayout { } } - override fun dispatchTouchEvent(ev: MotionEvent): Boolean { + gestureDetector.onTouchEvent(ev) // 捕获长按 + if (!disableMangaScale) { scaleDetector.onTouchEvent(ev) flingDetector.onTouchEvent(ev) @@ -99,7 +117,7 @@ class WebtoonFrame : FrameLayout { ev.setLocation( ev.x.coerceIn(recyclerRect.left.toFloat(), recyclerRect.right.toFloat()), - ev.y.coerceIn(recyclerRect.top.toFloat(), recyclerRect.bottom.toFloat()), + ev.y.coerceIn(recyclerRect.top.toFloat(), recyclerRect.bottom.toFloat()) ) } return super.dispatchTouchEvent(ev) @@ -134,15 +152,13 @@ class WebtoonFrame : FrameLayout { } inner class FlingListener : GestureDetector.SimpleOnGestureListener() { - override fun onDown(e: MotionEvent): Boolean { - return true - } + override fun onDown(e: MotionEvent): Boolean = true override fun onFling( e1: MotionEvent?, e2: MotionEvent, velocityX: Float, - velocityY: Float, + velocityY: Float ): Boolean { return recycler?.zoomFling(velocityX.toInt(), velocityY.toInt()) ?: false } @@ -155,5 +171,4 @@ class WebtoonFrame : FrameLayout { fun nextChapter() fun prevChapter() } - }