Tab快速选择

This commit is contained in:
HapeLee committed 2025-11-17 00:40:40 +08:00
1 parent 341b9c22ee
commit d4163ead56
9 files changed
+185 -41

No files matched your search

@@ -217,6 +217,7 @@ object PreferKey {
const val disableMangaScrollAnimation = "disableMangaScrollAnimation" const val disableMangaScrollAnimation = "disableMangaScrollAnimation"
const val disableMangaCrossFade = "disableMangaCrossFade" const val disableMangaCrossFade = "disableMangaCrossFade"
const val titleBarMode = "titleBarMode" const val titleBarMode = "titleBarMode"
const val shouldShowExpandButton = "shouldShowExpandButton"
} }
@@ -883,5 +883,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
set(value) { set(value) {
appCtx.putPrefBoolean(PreferKey.isPredictiveBackEnabled, value) appCtx.putPrefBoolean(PreferKey.isPredictiveBackEnabled, value)
} }
var shouldShowExpandButton: Boolean
get() = appCtx.getPrefBoolean(PreferKey.shouldShowExpandButton, false)
set(value) {
appCtx.putPrefBoolean(PreferKey.shouldShowExpandButton, value)
}
} }
@@ -31,12 +31,6 @@ class BookshelfConfigBottomSheet : BaseBottomSheetDialogFragment(R.layout.dialog
AppConfig.bookshelfLayoutModePortrait AppConfig.bookshelfLayoutModePortrait
} }
val isList = bookshelfLayout == 0
val isGrid = bookshelfLayout == 1
val isGridCompact = bookshelfLayout == 2
val isGridCover = bookshelfLayout == 3
val isListCompact = bookshelfLayout == 4
val columnCount = requireContext().bookshelfLayoutGrid.takeIf { it > 0 } ?: 1 val columnCount = requireContext().bookshelfLayoutGrid.takeIf { it > 0 } ?: 1
val bookshelfSort = AppConfig.bookshelfSort val bookshelfSort = AppConfig.bookshelfSort
@@ -73,27 +67,36 @@ class BookshelfConfigBottomSheet : BaseBottomSheetDialogFragment(R.layout.dialog
swShowLastUpdateTime.isChecked = AppConfig.showLastUpdateTime swShowLastUpdateTime.isChecked = AppConfig.showLastUpdateTime
swShowWaitUpBooks.isChecked = AppConfig.showWaitUpCount swShowWaitUpBooks.isChecked = AppConfig.showWaitUpCount
swShowBookshelfFastScroller.isChecked = AppConfig.showBookshelfFastScroller swShowBookshelfFastScroller.isChecked = AppConfig.showBookshelfFastScroller
swShowBookshelfTabMenu.isChecked = AppConfig.shouldShowExpandButton
when (bookshelfLayout) {
0 -> chipGroupLayout.check(R.id.chip_list)
1 -> chipGroupLayout.check(R.id.chip_grid)
2 -> chipGroupLayout.check(R.id.chip_grid_compact)
3 -> chipGroupLayout.check(R.id.chip_grid_cover)
4 -> chipGroupLayout.check(R.id.chip_list_compact)
}
chipList.isChecked = isList
chipListCompact.isChecked = isListCompact
chipGrid.isChecked = isGrid
chipGridCompact.isChecked = isGridCompact
chipGridCover.isChecked = isGridCover
sliderGridCount.progress = columnCount sliderGridCount.progress = columnCount
binding.tvValue.text = if (AppConfig.bookshelfRefreshingLimit <= 0) "无限制" updateControlsEnableState()
else "${AppConfig.bookshelfRefreshingLimit} 本"
chipGroupLayout.setOnCheckedStateChangeListener { group, checkedIds ->
updateControlsEnableState()
}
chipGroupStyle.setOnCheckedStateChangeListener { group, checkedIds ->
updateControlsEnableState()
}
binding.tvValue.text = if (AppConfig.bookshelfRefreshingLimit <= 0) "无限制"
else "${AppConfig.bookshelfRefreshingLimit} 本"
binding.tvValue.setOnClickListener {
showNumberPicker()
}
binding.layoutRefreshLimit.setOnClickListener { binding.layoutRefreshLimit.setOnClickListener {
NumberPickerDialog(requireContext()) showNumberPicker()
.setTitle("书架更新数量限制")
.setMinValue(0) // 0 表示无限制
.setMaxValue(500) // 可根据需求设定最大值
.setValue(AppConfig.bookshelfRefreshingLimit)
.show { selected ->
AppConfig.bookshelfRefreshingLimit = selected
tvValue.text = if (selected <= 0) "无限制" else "$selected 本"
}
} }
when (AppConfig.bookshelfSortOrder) { when (AppConfig.bookshelfSortOrder) {
@@ -128,19 +131,22 @@ class BookshelfConfigBottomSheet : BaseBottomSheetDialogFragment(R.layout.dialog
AppConfig.showBookshelfFastScroller = swShowBookshelfFastScroller.isChecked AppConfig.showBookshelfFastScroller = swShowBookshelfFastScroller.isChecked
postEvent(EventBus.BOOKSHELF_REFRESH, "") postEvent(EventBus.BOOKSHELF_REFRESH, "")
} }
if (AppConfig.shouldShowExpandButton != swShowBookshelfTabMenu.isChecked) {
AppConfig.shouldShowExpandButton = swShowBookshelfTabMenu.isChecked
postEvent(EventBus.BOOKSHELF_REFRESH, "")
}
if (bookshelfSort != chipGroupSort.checkedChipId) { if (bookshelfSort != chipGroupSort.checkedChipId) {
AppConfig.bookshelfSort = chipGroupSort.checkedChipId AppConfig.bookshelfSort = chipGroupSort.checkedChipId
(requireParentFragment() as? BaseBookshelfFragment)?.upSort() (requireParentFragment() as? BaseBookshelfFragment)?.upSort()
} }
val selectedColumn = sliderGridCount.progress val selectedColumn = sliderGridCount.progress
val newLayout = when { val newLayout = when (chipGroupLayout.checkedChipId) {
chipList.isChecked -> 0 R.id.chip_list -> 0
chipGrid.isChecked -> 1 R.id.chip_grid -> 1
chipGridCompact.isChecked -> 2 R.id.chip_grid_compact -> 2
chipGridCover.isChecked -> 3 R.id.chip_grid_cover -> 3
chipListCompact.isChecked -> 4 R.id.chip_list_compact -> 4
else -> 0 else -> 0
} }
@@ -187,4 +193,26 @@ class BookshelfConfigBottomSheet : BaseBottomSheetDialogFragment(R.layout.dialog
} }
} }
} }
private fun showNumberPicker() {
NumberPickerDialog(requireContext())
.setTitle("书架更新数量限制")
.setMinValue(0) // 0 表示无限制
.setMaxValue(500) // 可根据需求设定最大值
.setValue(AppConfig.bookshelfRefreshingLimit)
.show { selected ->
AppConfig.bookshelfRefreshingLimit = selected
binding.tvValue.text = if (selected <= 0) "无限制" else "$selected 本"
}
}
private fun updateControlsEnableState() {
val checkedLayoutId = binding.chipGroupLayout.checkedChipId
val isListMode = checkedLayoutId == R.id.chip_list || checkedLayoutId == R.id.chip_list_compact
binding.swShowLastUpdateTime.isEnabled = isListMode
val checkedStyleChip = binding.chipGroupStyle.findViewById<Chip>(binding.chipGroupStyle.checkedChipId)
val isGroupStyle0 = binding.chipGroupStyle.indexOfChild(checkedStyleChip) == 0
binding.swShowBookshelfTabMenu.isEnabled = isGroupStyle0
}
} }
@@ -3,9 +3,12 @@
package io.legado.app.ui.main.bookshelf.books package io.legado.app.ui.main.bookshelf.books
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.adapter.FragmentStateAdapter
@@ -21,6 +24,7 @@ import io.legado.app.ui.book.group.GroupEditDialog
import io.legado.app.ui.book.search.SearchActivity import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.main.bookshelf.BaseBookshelfFragment import io.legado.app.ui.main.bookshelf.BaseBookshelfFragment
import io.legado.app.utils.showDialogFragment import io.legado.app.utils.showDialogFragment
import io.legado.app.utils.themeColor
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlin.collections.set import kotlin.collections.set
@@ -58,6 +62,7 @@ class BookshelfFragment1() : BaseBookshelfFragment(R.layout.fragment_bookshelf1)
binding.titleBar.fitsSystemWindows = true binding.titleBar.fitsSystemWindows = true
initView() initView()
initBookGroupData() initBookGroupData()
setupExpandButton()
} }
private val selectedGroup: BookGroup? private val selectedGroup: BookGroup?
@@ -71,6 +76,58 @@ class BookshelfFragment1() : BaseBookshelfFragment(R.layout.fragment_bookshelf1)
TabLayoutMediator(binding.tabLayout, binding.viewPagerBookshelf) { tab, position -> TabLayoutMediator(binding.tabLayout, binding.viewPagerBookshelf) { tab, position ->
tab.text = bookGroups[position].groupName tab.text = bookGroups[position].groupName
}.attach() }.attach()
updateTabFadeEffect()
}
private fun setupExpandButton() {
binding.btnExpandTabs.setOnClickListener {
showTabSelectionMenu()
}
}
private fun updateTabFadeEffect() {
binding.titleBar.addOnOffsetChangedListener({ appBarLayout, verticalOffset ->
if (-verticalOffset >= appBarLayout.totalScrollRange) {
val drawable = binding.tabRightFade.background as? GradientDrawable
drawable?.colors = intArrayOf(Color.TRANSPARENT,
requireContext().themeColor(com.google.android.material.R.attr.colorSurfaceContainer))
} else {
val drawable = binding.tabRightFade.background as? GradientDrawable
drawable?.colors = intArrayOf(Color.TRANSPARENT,
requireContext().themeColor(com.google.android.material.R.attr.colorSurface))
}
})
}
private fun showTabSelectionMenu() {
val popup = PopupMenu(requireContext(), binding.btnExpandTabs)
bookGroups.forEachIndexed { index, bookGroup ->
popup.menu.add(0, index, index, bookGroup.groupName)
}
popup.setOnMenuItemClickListener { item ->
val position = item.itemId
if (position in bookGroups.indices) {
binding.viewPagerBookshelf.setCurrentItem(position, true)
}
true
}
popup.setOnDismissListener {
binding.btnExpandTabs.isChecked = false
}
popup.show()
}
private fun updateExpandButtonVisibility() {
binding.btnExpandTabs.visibility = if (AppConfig.shouldShowExpandButton) {
View.VISIBLE
} else {
View.GONE
}
} }
override fun onQueryTextSubmit(query: String?): Boolean { override fun onQueryTextSubmit(query: String?): Boolean {
@@ -99,6 +156,8 @@ class BookshelfFragment1() : BaseBookshelfFragment(R.layout.fragment_bookshelf1)
tab.text = bookGroups[position].groupName tab.text = bookGroups[position].groupName
}.attach() }.attach()
updateExpandButtonVisibility()
updateTabFadeEffect()
selectLastTab() selectLastTab()
binding.tabLayout.post { binding.tabLayout.post {
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -67,14 +66,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/show_bookshelf_fast_scroller" /> android:text="@string/show_bookshelf_fast_scroller" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/sw_show_bookshelf_tab_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/show_bookshelf_tab_menu" />
<LinearLayout <LinearLayout
android:id="@+id/layout_refresh_limit" android:id="@+id/layout_refresh_limit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingHorizontal="2dp"
android:orientation="horizontal" android:orientation="horizontal"
android:clickable="true" android:clickable="true">
android:background="?attr/selectableItemBackground">
<TextView <TextView
android:id="@+id/tv_title" android:id="@+id/tv_title"
@@ -84,10 +87,17 @@
android:paddingVertical="16dp" android:paddingVertical="16dp"
android:text="@string/bookshelf_update_limit" /> android:text="@string/bookshelf_update_limit" />
<TextView <com.google.android.material.button.MaterialButton
android:id="@+id/tv_value" android:id="@+id/tv_value"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"
android:clickable="true"
android:minWidth="0dp"
android:minHeight="0dp"
android:paddingHorizontal="0dp"
android:paddingVertical="8dp"
style="@style/Widget.Material3Expressive.Button.OutlinedButton"/>
</LinearLayout> </LinearLayout>
<TextView <TextView
@@ -33,12 +33,49 @@
</com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.CollapsingToolbarLayout>
<com.google.android.material.tabs.TabLayout <LinearLayout
android:id="@+id/tab_layout" android:id="@+id/ll_tab"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@android:color/transparent" android:orientation="horizontal"
android:paddingHorizontal="16dp"/> android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="10dp">
<FrameLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clipToPadding="false"
android:clipChildren="false">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
app:tabMode="scrollable"
android:scrollbars="none" />
<View
android:id="@+id/tab_right_fade"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:background="@drawable/tab_right_fade" />
</FrameLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_expand_tabs"
android:layout_width="40dp"
android:layout_height="40dp"
android:checkable="true"
app:iconGravity="textStart"
style="@style/Widget.Material3Expressive.Button.IconButton.Outlined"
app:icon="@drawable/m3_split_button_chevron_avd" />
</LinearLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
+1
View File
@@ -1348,4 +1348,5 @@
<string name="sure_cache_book">是否确认开始缓存?</string> <string name="sure_cache_book">是否确认开始缓存?</string>
<string name="replace_purify_badge">计数替换净化</string> <string name="replace_purify_badge">计数替换净化</string>
<string name="page_anim_fade">渐变</string> <string name="page_anim_fade">渐变</string>
<string name="show_bookshelf_tab_menu">显示更多分组按钮</string>
</resources> </resources>
+1
View File
@@ -1349,4 +1349,5 @@
<string name="sure_cache_book">是否确认开始缓存?</string> <string name="sure_cache_book">是否确认开始缓存?</string>
<string name="replace_purify_badge">计数替换净化</string> <string name="replace_purify_badge">计数替换净化</string>
<string name="page_anim_fade">渐变</string> <string name="page_anim_fade">渐变</string>
<string name="show_bookshelf_tab_menu">显示更多分组按钮</string>
</resources> </resources>
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION_MAJOR=3 VERSION_MAJOR=3
VERSION_MINOR=26 VERSION_MINOR=26
VERSION_PATCH=3 VERSION_PATCH=3
VERSION_SUFFIX=-beta.5 VERSION_SUFFIX=-beta.6