Просмотр исходного кода

添加书签快速定位至目录的功能

HapeLee 1 год назад
Родитель
Сommit
f123ef2eaa

+ 6 - 0
app/src/main/java/io/legato/kazusa/ui/book/toc/BookmarkAdapter.kt

@@ -41,11 +41,17 @@ class BookmarkAdapter(context: Context, val callback: Callback) :
                 callback.onClick(bookmark)
             }
         }
+        binding.btnLocate.onClick {
+            getItem(holder.layoutPosition)?.let { bookmark ->
+                callback.onLocate(bookmark)
+            }
+        }
     }
 
     interface Callback {
         fun onClick(bookmark: Bookmark)
         fun onLongClick(bookmark: Bookmark, pos: Int)
+        fun onLocate(bookmark: Bookmark)
     }
 
 }

+ 4 - 4
app/src/main/java/io/legato/kazusa/ui/book/toc/BookmarkFragment.kt

@@ -12,10 +12,8 @@ import io.legato.kazusa.constant.AppLog
 import io.legato.kazusa.data.appDb
 import io.legato.kazusa.data.entities.Bookmark
 import io.legato.kazusa.databinding.FragmentBookmarkBinding
-//import io.legado.app.lib.theme.primaryColor
 import io.legato.kazusa.ui.book.bookmark.BookmarkDialog
 import io.legato.kazusa.ui.widget.recycler.UpLinearLayoutManager
-import io.legato.kazusa.ui.widget.recycler.VerticalDivider
 import io.legato.kazusa.utils.applyNavigationBarPadding
 import io.legato.kazusa.utils.showDialogFragment
 import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
@@ -49,10 +47,8 @@ class BookmarkFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_bookmark
     private fun initRecyclerView() {
         //binding.recyclerView.setEdgeEffectColor(primaryColor)
         binding.recyclerView.layoutManager = mLayoutManager
-        binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
         binding.recyclerView.adapter = adapter
         binding.recyclerView.applyNavigationBarPadding()
-
         binding.tvEmptyMsg.visible(false)
     }
 
@@ -96,4 +92,8 @@ class BookmarkFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_bookmark
         showDialogFragment(BookmarkDialog(bookmark, pos))
     }
 
+    override fun onLocate(bookmark: Bookmark) {
+        (activity as? TocActivity)?.locateToChapter(bookmark.chapterIndex)
+    }
+
 }

+ 1 - 1
app/src/main/java/io/legato/kazusa/ui/book/toc/ChapterListAdapter.kt

@@ -212,7 +212,7 @@ class ChapterListAdapter(
 
             if (selectedIndices.contains(item.index)) {
                 ivVolume.gone()
-                tvChapterItem.setBackgroundColor(context.themeColor(com.google.android.material.R.attr.colorSurfaceBright))
+                tvChapterItem.setBackgroundColor(context.themeColor(com.google.android.material.R.attr.colorSurfaceContainerHighest))
             } else {
                 if (item.isVolume) {
                     ivVolume.visible()

+ 33 - 0
app/src/main/java/io/legato/kazusa/ui/book/toc/ChapterListFragment.kt

@@ -1,10 +1,14 @@
 package io.legato.kazusa.ui.book.toc
 
+import android.animation.ArgbEvaluator
+import android.animation.ValueAnimator
 import android.annotation.SuppressLint
 import android.app.Activity.RESULT_OK
 import android.content.Intent
 import android.graphics.Canvas
+import android.graphics.Color
 import android.graphics.Rect
+import android.graphics.drawable.ColorDrawable
 import android.os.Bundle
 import android.transition.TransitionManager
 import android.view.View
@@ -260,6 +264,35 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
         }
     }
 
+    fun scrollToChapter(chapterIndex: Int) {
+        val pos = adapter.getItems().indexOfFirst { it.index == chapterIndex }
+        if (pos != -1) {
+            mLayoutManager.scrollToPositionWithOffset(pos, 0)
+
+            binding.recyclerView.post {
+                val holder = binding.recyclerView.findViewHolderForAdapterPosition(pos)
+                holder?.itemView?.let { view ->
+                    flashHighlight(view)
+                }
+            }
+        }
+    }
+
+    private fun flashHighlight(view: View) {
+        val highlightColor = context?.themeColor(com.google.android.material.R.attr.colorSurfaceContainerHighest)
+        val originalColor = (view.background as? ColorDrawable)?.color ?: Color.TRANSPARENT
+        val anim = ValueAnimator.ofObject(ArgbEvaluator(), originalColor, highlightColor, originalColor).apply {
+            duration = 500
+            repeatCount = 1
+            repeatMode = ValueAnimator.RESTART
+            addUpdateListener { animator ->
+                val color = animator.animatedValue as Int
+                view.setBackgroundColor(color)
+            }
+        }
+        anim.start()
+    }
+
 
     override fun onSelectionModeChanged(enabled: Boolean) {
         TransitionManager.beginDelayedTransition(binding.coordinatorLayout, MaterialFadeThrough())

+ 9 - 0
app/src/main/java/io/legato/kazusa/ui/book/toc/TocActivity.kt

@@ -210,6 +210,15 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>(),
         }
     }
 
+    fun locateToChapter(index: Int) {
+        val tag = "android:switcher:${binding.viewPager.id}:0"
+        val chapterFragment = supportFragmentManager.findFragmentByTag(tag) as? ChapterListFragment
+        chapterFragment?.scrollToChapter(index)
+
+        binding.viewPager.currentItem = 0
+    }
+
+
     @SuppressLint("SetTextI18n")
     fun showDownloadDialog() {
         ReadBook.book?.let { book ->

+ 50 - 24
app/src/main/res/layout/item_bookmark.xml

@@ -1,34 +1,60 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingHorizontal="16dp"
+    android:paddingStart="16dp"
+    android:paddingEnd="10dp"
     android:paddingVertical="12dp"
     android:background="?attr/selectableItemBackground">
 
-    <TextView
-        android:id="@+id/tv_chapter_name"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingBottom="2dp"
-        android:textSize="16sp"
-        android:textStyle="bold" />
+    <com.google.android.material.button.MaterialButton
+        android:id="@+id/btn_locate"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        app:iconSize="16dp"
+        app:iconGravity="textStart"
+        app:icon="@drawable/ic_locate"
+        style="@style/Widget.Material3Expressive.Button.IconButton.Outlined"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"/>
 
-    <TextView
-        android:id="@+id/tv_book_text"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingBottom="2dp"
-        android:textSize="14sp"
-        android:singleLine="true" />
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:layout_marginEnd="8dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/btn_locate"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent">
+        <TextView
+            android:id="@+id/tv_chapter_name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="2dp"
+            android:textSize="16sp"
+            android:textStyle="bold" />
 
-    <TextView
-        android:id="@+id/tv_content"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textColor="?attr/colorSecondary"
-        android:textSize="12sp"
-        android:singleLine="true" />
+        <TextView
+            android:id="@+id/tv_book_text"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingBottom="2dp"
+            android:textSize="13sp"
+            android:singleLine="true" />
 
-</LinearLayout>
+        <TextView
+            android:id="@+id/tv_content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textColor="?attr/colorSecondary"
+            android:textSize="12sp"
+            android:singleLine="true" />
+    </LinearLayout>
+
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>