本地书籍
This commit is contained in:
3 files changed
+98
-88
No files matched your search
@@ -14,6 +14,7 @@ import android.transition.TransitionManager
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.graphics.drawable.toDrawable
|
import androidx.core.graphics.drawable.toDrawable
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
@@ -58,6 +59,7 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
|
|||||||
private val mLayoutManager by lazy { UpLinearLayoutManager(requireContext()) }
|
private val mLayoutManager by lazy { UpLinearLayoutManager(requireContext()) }
|
||||||
private val adapter by lazy { ChapterListAdapter(requireContext(), this) }
|
private val adapter by lazy { ChapterListAdapter(requireContext(), this) }
|
||||||
private var durChapterIndex = 0
|
private var durChapterIndex = 0
|
||||||
|
private var swipeHelper: ItemTouchHelper? = null
|
||||||
|
|
||||||
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) = binding.run {
|
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) = binding.run {
|
||||||
viewModel.chapterListCallBack = this@ChapterListFragment
|
viewModel.chapterListCallBack = this@ChapterListFragment
|
||||||
@@ -65,98 +67,12 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
|
|||||||
initView()
|
initView()
|
||||||
viewModel.bookData.observe(this@ChapterListFragment) {
|
viewModel.bookData.observe(this@ChapterListFragment) {
|
||||||
initBook(it)
|
initBook(it)
|
||||||
|
initSwipeIfNeed(it.isLocal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initRecyclerView() {
|
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.layoutManager = mLayoutManager
|
||||||
|
|
||||||
binding.recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
binding.recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
|
||||||
override fun getItemOffsets(
|
override fun getItemOffsets(
|
||||||
outRect: Rect,
|
outRect: Rect,
|
||||||
@@ -173,6 +89,97 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
|
|||||||
binding.recyclerView.adapter = adapter
|
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 {
|
private fun initView() = binding.run {
|
||||||
llBase.applyNavigationBarPadding()
|
llBase.applyNavigationBarPadding()
|
||||||
btnChapterTop.setOnClickListener {
|
btnChapterTop.setOnClickListener {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import io.legado.app.data.entities.Book
|
|||||||
import io.legado.app.data.entities.BookChapter
|
import io.legado.app.data.entities.BookChapter
|
||||||
import io.legado.app.databinding.ActivityChapterListBinding
|
import io.legado.app.databinding.ActivityChapterListBinding
|
||||||
import io.legado.app.databinding.DialogDownloadChoiceBinding
|
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.book.isLocalTxt
|
||||||
import io.legado.app.help.config.AppConfig
|
import io.legado.app.help.config.AppConfig
|
||||||
import io.legado.app.lib.dialogs.alert
|
import io.legado.app.lib.dialogs.alert
|
||||||
@@ -64,6 +65,7 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>(),
|
|||||||
private var menu: Menu? = null
|
private var menu: Menu? = null
|
||||||
private var searchView: SearchView? = null
|
private var searchView: SearchView? = null
|
||||||
private val waitDialog by lazy { WaitDialog(this) }
|
private val waitDialog by lazy { WaitDialog(this) }
|
||||||
|
private var isLocalBook : Boolean = false
|
||||||
private val exportDir = registerForActivityResult(HandleFileContract()) {
|
private val exportDir = registerForActivityResult(HandleFileContract()) {
|
||||||
it.uri?.let { uri ->
|
it.uri?.let { uri ->
|
||||||
when (it.requestCode) {
|
when (it.requestCode) {
|
||||||
@@ -88,6 +90,7 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>(),
|
|||||||
viewModel.bookData.observe(this) { book ->
|
viewModel.bookData.observe(this) { book ->
|
||||||
menu?.setGroupVisible(R.id.menu_group_text, book.isLocalTxt)
|
menu?.setGroupVisible(R.id.menu_group_text, book.isLocalTxt)
|
||||||
supportActionBar?.title = book.name
|
supportActionBar?.title = book.name
|
||||||
|
binding.topBar.menu.findItem(R.id.menu_download)?.isVisible = !book.isLocal
|
||||||
}
|
}
|
||||||
intent.getStringExtra("bookUrl")?.let {
|
intent.getStringExtra("bookUrl")?.let {
|
||||||
viewModel.initBook(it)
|
viewModel.initBook(it)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ coreSplashscreen = "1.2.0-rc01"
|
|||||||
datastorePreferences = "1.1.7"
|
datastorePreferences = "1.1.7"
|
||||||
kotlin = "2.2.20"
|
kotlin = "2.2.20"
|
||||||
ksp = "2.2.20-2.0.4"
|
ksp = "2.2.20-2.0.4"
|
||||||
agp = "8.13.0"
|
agp = "8.13.1"
|
||||||
appcompat = "1.7.1"
|
appcompat = "1.7.1"
|
||||||
colorpicker = "1.1.0"
|
colorpicker = "1.1.0"
|
||||||
commonsText = "1.14.0"
|
commonsText = "1.14.0"
|
||||||
|
|||||||
Reference in new issue
Block a user