diff --git a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt index 640aa08ef..ebeacf25c 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt @@ -14,6 +14,7 @@ import android.transition.TransitionManager import android.view.View import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.toDrawable +import androidx.core.view.isVisible import androidx.fragment.app.activityViewModels import androidx.interpolator.view.animation.FastOutSlowInInterpolator import androidx.lifecycle.lifecycleScope @@ -58,6 +59,7 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragment_chapt private val mLayoutManager by lazy { UpLinearLayoutManager(requireContext()) } private val adapter by lazy { ChapterListAdapter(requireContext(), this) } private var durChapterIndex = 0 + private var swipeHelper: ItemTouchHelper? = null override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) = binding.run { viewModel.chapterListCallBack = this@ChapterListFragment @@ -65,98 +67,12 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragment_chapt initView() viewModel.bookData.observe(this@ChapterListFragment) { initBook(it) + initSwipeIfNeed(it.isLocal) } } private fun initRecyclerView() { - val swipeCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) { - - override fun onMove( - recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder, - target: RecyclerView.ViewHolder - ): Boolean = false - - override fun getSwipeThreshold(viewHolder: RecyclerView.ViewHolder): Float = 0.3f - - override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { - val position = viewHolder.bindingAdapterPosition - val chapter = adapter.getItem(position) ?: return - val book = book ?: return - - toastOnUi("开始下载: ${adapter.getItem(position)?.title}") - CacheBook.start(requireContext(), book, listOf(chapter.index)) - VibrationUtils.vibratePattern(requireContext(), longArrayOf(0, 50, 30, 50), -1) - adapter.notifyItemChanged(position) - } - - override fun onChildDraw( - c: Canvas, - recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder, - dX: Float, - dY: Float, - actionState: Int, - isCurrentlyActive: Boolean - ) { - if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE && dX > 0) { - val itemView = viewHolder.itemView - - val interpolator = FastOutSlowInInterpolator() - val dampedDx = - interpolator.getInterpolation(min(1f, dX / itemView.width)) * itemView.width - - // 背景 - val background = - requireContext().themeColor(com.google.android.material.R.attr.colorSecondary) - .toDrawable() - background.setBounds( - itemView.left, - itemView.top, - itemView.left + dampedDx.toInt(), - itemView.bottom - ) - background.draw(c) - - // 图标 - val icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_download)!! - val iconMargin = (itemView.height - icon.intrinsicHeight) / 2 - val iconTop = itemView.top + iconMargin - val iconBottom = iconTop + icon.intrinsicHeight - val iconLeft = 12.dpToPx() - val iconRight = iconLeft + icon.intrinsicWidth - icon.setTint(requireContext().themeColor(com.google.android.material.R.attr.colorOnSecondary)) - icon.setBounds(iconLeft, iconTop, iconRight, iconBottom) - icon.draw(c) - - super.onChildDraw( - c, - recyclerView, - viewHolder, - dampedDx, - dY, - actionState, - isCurrentlyActive - ) - } else { - super.onChildDraw( - c, - recyclerView, - viewHolder, - dX, - dY, - actionState, - isCurrentlyActive - ) - } - } - } - - val itemTouchHelper = ItemTouchHelper(swipeCallback) - itemTouchHelper.attachToRecyclerView(binding.recyclerView) - binding.recyclerView.layoutManager = mLayoutManager - binding.recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() { override fun getItemOffsets( outRect: Rect, @@ -173,6 +89,97 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragment_chapt binding.recyclerView.adapter = adapter } + private fun initSwipeIfNeed(isLocalBook: Boolean) { + binding.btnDownloadSelected.isEnabled = !isLocalBook + swipeHelper?.attachToRecyclerView(null) + if (!isLocalBook){ + val swipeCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) { + + override fun onMove( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder, + target: RecyclerView.ViewHolder + ): Boolean = false + + override fun getSwipeThreshold(viewHolder: RecyclerView.ViewHolder): Float = 0.3f + + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + val position = viewHolder.bindingAdapterPosition + val chapter = adapter.getItem(position) ?: return + val book = book ?: return + + toastOnUi("开始下载: ${adapter.getItem(position)?.title}") + CacheBook.start(requireContext(), book, listOf(chapter.index)) + VibrationUtils.vibratePattern(requireContext(), longArrayOf(0, 50, 30, 50), -1) + adapter.notifyItemChanged(position) + } + + override fun onChildDraw( + c: Canvas, + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder, + dX: Float, + dY: Float, + actionState: Int, + isCurrentlyActive: Boolean + ) { + if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE && dX > 0) { + val itemView = viewHolder.itemView + + val interpolator = FastOutSlowInInterpolator() + val dampedDx = + interpolator.getInterpolation(min(1f, dX / itemView.width)) * itemView.width + + // 背景 + val background = + requireContext().themeColor(com.google.android.material.R.attr.colorSecondary) + .toDrawable() + background.setBounds( + itemView.left, + itemView.top, + itemView.left + dampedDx.toInt(), + itemView.bottom + ) + background.draw(c) + + // 图标 + val icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_download)!! + val iconMargin = (itemView.height - icon.intrinsicHeight) / 2 + val iconTop = itemView.top + iconMargin + val iconBottom = iconTop + icon.intrinsicHeight + val iconLeft = 12.dpToPx() + val iconRight = iconLeft + icon.intrinsicWidth + icon.setTint(requireContext().themeColor(com.google.android.material.R.attr.colorOnSecondary)) + icon.setBounds(iconLeft, iconTop, iconRight, iconBottom) + icon.draw(c) + + super.onChildDraw( + c, + recyclerView, + viewHolder, + dampedDx, + dY, + actionState, + isCurrentlyActive + ) + } else { + super.onChildDraw( + c, + recyclerView, + viewHolder, + dX, + dY, + actionState, + isCurrentlyActive + ) + } + } + } + val itemTouchHelper = ItemTouchHelper(swipeCallback) + itemTouchHelper.attachToRecyclerView(binding.recyclerView) + } + } + private fun initView() = binding.run { llBase.applyNavigationBarPadding() btnChapterTop.setOnClickListener { diff --git a/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt b/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt index bc7f71751..af0179501 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt @@ -31,6 +31,7 @@ import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.databinding.ActivityChapterListBinding import io.legado.app.databinding.DialogDownloadChoiceBinding +import io.legado.app.help.book.isLocal import io.legado.app.help.book.isLocalTxt import io.legado.app.help.config.AppConfig import io.legado.app.lib.dialogs.alert @@ -64,6 +65,7 @@ class TocActivity : VMBaseActivity(), private var menu: Menu? = null private var searchView: SearchView? = null private val waitDialog by lazy { WaitDialog(this) } + private var isLocalBook : Boolean = false private val exportDir = registerForActivityResult(HandleFileContract()) { it.uri?.let { uri -> when (it.requestCode) { @@ -88,6 +90,7 @@ class TocActivity : VMBaseActivity(), viewModel.bookData.observe(this) { book -> menu?.setGroupVisible(R.id.menu_group_text, book.isLocalTxt) supportActionBar?.title = book.name + binding.topBar.menu.findItem(R.id.menu_download)?.isVisible = !book.isLocal } intent.getStringExtra("bookUrl")?.let { viewModel.initBook(it) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a3c9f9560..1c43df011 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ coreSplashscreen = "1.2.0-rc01" datastorePreferences = "1.1.7" kotlin = "2.2.20" ksp = "2.2.20-2.0.4" -agp = "8.13.0" +agp = "8.13.1" appcompat = "1.7.1" colorpicker = "1.1.0" commonsText = "1.14.0"