|
@@ -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 {
|