添加书签快速定位至目录的功能
This commit is contained in:
@@ -41,11 +41,17 @@ class BookmarkAdapter(context: Context, val callback: Callback) :
|
|||||||
callback.onClick(bookmark)
|
callback.onClick(bookmark)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
binding.btnLocate.onClick {
|
||||||
|
getItem(holder.layoutPosition)?.let { bookmark ->
|
||||||
|
callback.onLocate(bookmark)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
fun onClick(bookmark: Bookmark)
|
fun onClick(bookmark: Bookmark)
|
||||||
fun onLongClick(bookmark: Bookmark, pos: Int)
|
fun onLongClick(bookmark: Bookmark, pos: Int)
|
||||||
|
fun onLocate(bookmark: Bookmark)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -12,10 +12,8 @@ import io.legato.kazusa.constant.AppLog
|
|||||||
import io.legato.kazusa.data.appDb
|
import io.legato.kazusa.data.appDb
|
||||||
import io.legato.kazusa.data.entities.Bookmark
|
import io.legato.kazusa.data.entities.Bookmark
|
||||||
import io.legato.kazusa.databinding.FragmentBookmarkBinding
|
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.book.bookmark.BookmarkDialog
|
||||||
import io.legato.kazusa.ui.widget.recycler.UpLinearLayoutManager
|
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.applyNavigationBarPadding
|
||||||
import io.legato.kazusa.utils.showDialogFragment
|
import io.legato.kazusa.utils.showDialogFragment
|
||||||
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
|
||||||
@@ -49,10 +47,8 @@ class BookmarkFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_bookmark
|
|||||||
private fun initRecyclerView() {
|
private fun initRecyclerView() {
|
||||||
//binding.recyclerView.setEdgeEffectColor(primaryColor)
|
//binding.recyclerView.setEdgeEffectColor(primaryColor)
|
||||||
binding.recyclerView.layoutManager = mLayoutManager
|
binding.recyclerView.layoutManager = mLayoutManager
|
||||||
binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
|
|
||||||
binding.recyclerView.adapter = adapter
|
binding.recyclerView.adapter = adapter
|
||||||
binding.recyclerView.applyNavigationBarPadding()
|
binding.recyclerView.applyNavigationBarPadding()
|
||||||
|
|
||||||
binding.tvEmptyMsg.visible(false)
|
binding.tvEmptyMsg.visible(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,4 +92,8 @@ class BookmarkFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_bookmark
|
|||||||
showDialogFragment(BookmarkDialog(bookmark, pos))
|
showDialogFragment(BookmarkDialog(bookmark, pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onLocate(bookmark: Bookmark) {
|
||||||
|
(activity as? TocActivity)?.locateToChapter(bookmark.chapterIndex)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -212,7 +212,7 @@ class ChapterListAdapter(
|
|||||||
|
|
||||||
if (selectedIndices.contains(item.index)) {
|
if (selectedIndices.contains(item.index)) {
|
||||||
ivVolume.gone()
|
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 {
|
} else {
|
||||||
if (item.isVolume) {
|
if (item.isVolume) {
|
||||||
ivVolume.visible()
|
ivVolume.visible()
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
package io.legato.kazusa.ui.book.toc
|
package io.legato.kazusa.ui.book.toc
|
||||||
|
|
||||||
|
import android.animation.ArgbEvaluator
|
||||||
|
import android.animation.ValueAnimator
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity.RESULT_OK
|
import android.app.Activity.RESULT_OK
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Color
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.transition.TransitionManager
|
import android.transition.TransitionManager
|
||||||
import android.view.View
|
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) {
|
override fun onSelectionModeChanged(enabled: Boolean) {
|
||||||
TransitionManager.beginDelayedTransition(binding.coordinatorLayout, MaterialFadeThrough())
|
TransitionManager.beginDelayedTransition(binding.coordinatorLayout, MaterialFadeThrough())
|
||||||
|
|||||||
@@ -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")
|
@SuppressLint("SetTextI18n")
|
||||||
fun showDownloadDialog() {
|
fun showDownloadDialog() {
|
||||||
ReadBook.book?.let { book ->
|
ReadBook.book?.let { book ->
|
||||||
|
|||||||
@@ -1,34 +1,60 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingHorizontal="16dp"
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="10dp"
|
||||||
android:paddingVertical="12dp"
|
android:paddingVertical="12dp"
|
||||||
android:background="?attr/selectableItemBackground">
|
android:background="?attr/selectableItemBackground">
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/tv_chapter_name"
|
android:id="@+id/btn_locate"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="40dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="40dp"
|
||||||
android:paddingBottom="2dp"
|
app:iconSize="16dp"
|
||||||
android:textSize="16sp"
|
app:iconGravity="textStart"
|
||||||
android:textStyle="bold" />
|
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
|
<LinearLayout
|
||||||
android:id="@+id/tv_book_text"
|
android:layout_width="0dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:orientation="vertical"
|
||||||
android:paddingBottom="2dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:textSize="14sp"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
android:singleLine="true" />
|
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
|
<TextView
|
||||||
android:id="@+id/tv_content"
|
android:id="@+id/tv_book_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="?attr/colorSecondary"
|
android:paddingBottom="2dp"
|
||||||
android:textSize="12sp"
|
android:textSize="13sp"
|
||||||
android:singleLine="true" />
|
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>
|
||||||
Reference in New Issue
Block a user