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

1.整理设置界面,将有关主页面外观的设置移至[外观]设置中
2.将部分控件更换为M3E样式
3.增加导航栏标签显示自定义设置
4.现在轨道导航可以记住上次的扩展位置
5.优化共享动画
6.更新一些颜文字
7.清理代码

HapeLee 1 год назад
Родитель
Сommit
480dfdeb62
25 измененных файлов с 362 добавлено и 257 удалено
  1. 2 2
      .github/workflows/test.yml
  2. 1 1
      app/src/main/java/io/legato/kazusa/constant/PreferKey.kt
  3. 6 0
      app/src/main/java/io/legato/kazusa/help/config/AppConfig.kt
  4. 6 0
      app/src/main/java/io/legato/kazusa/help/config/LocalConfig.kt
  5. 0 2
      app/src/main/java/io/legato/kazusa/ui/config/OtherConfigFragment.kt
  6. 3 3
      app/src/main/java/io/legato/kazusa/ui/config/ThemeConfigFragment.kt
  7. 51 35
      app/src/main/java/io/legato/kazusa/ui/main/MainActivity.kt
  8. 3 3
      app/src/main/java/io/legato/kazusa/ui/main/bookshelf/books/styleDefalut/BooksAdapterList.kt
  9. 2 2
      app/src/main/java/io/legato/kazusa/ui/main/bookshelf/books/styleFold/BooksAdapterList.kt
  10. 1 6
      app/src/main/java/io/legato/kazusa/ui/widget/EmptyMessageView.kt
  11. 14 0
      app/src/main/res/drawable/ic_menu_open.xml
  12. 2 1
      app/src/main/res/layout/activity_book_search.xml
  13. 2 4
      app/src/main/res/layout/activity_main.xml
  14. 46 49
      app/src/main/res/layout/item_bookshelf_grid.xml
  15. 65 57
      app/src/main/res/layout/item_bookshelf_list.xml
  16. 3 3
      app/src/main/res/layout/item_fillet_text.xml
  17. 7 1
      app/src/main/res/layout/navigation_rail_fab.xml
  18. 2 0
      app/src/main/res/values-night/themes.xml
  19. 7 0
      app/src/main/res/values-zh/arrays.xml
  20. 7 0
      app/src/main/res/values/array_values.xml
  21. 7 0
      app/src/main/res/values/arrays.xml
  22. 0 3
      app/src/main/res/values/dimens.xml
  23. 2 0
      app/src/main/res/values/themes.xml
  24. 70 78
      app/src/main/res/xml/pref_config_other.xml
  25. 53 7
      app/src/main/res/xml/pref_config_theme.xml

+ 2 - 2
.github/workflows/test.yml

@@ -114,8 +114,8 @@ jobs:
       - name: Check Build production
         run: |
           echo "查看 APK 输出目录"
-          ls -R $GITHUB_WORKSPACE/app/app/build/outputs/apk/
-          if ! ls $GITHUB_WORKSPACE/app/app/build/outputs/apk/release/*/*.apk 1> /dev/null 2>&1; then
+          ls -R $GITHUB_WORKSPACE/app/build/outputs/apk/
+          if ! ls $GITHUB_WORKSPACE/app/build/outputs/apk/*/*/*.apk 1> /dev/null 2>&1; then
             echo "Build production not found! Check gradle logs."
             exit 1
           fi

+ 1 - 1
app/src/main/java/io/legato/kazusa/constant/PreferKey.kt

@@ -103,7 +103,6 @@ object PreferKey {
     const val mangaColorFilter = "mangaColorFilter"
     const val enableMangaEInk = "enableMangaEInk"
     const val mangaEInkThreshold = "mangaEInkThreshold"
-    const val disableHorizontalAnimator = "disableHorizontalAnimator"
     const val enableMangaGray = "enableMangaGray"
 
     const val autoRefresh = "auto_refresh"
@@ -204,4 +203,5 @@ object PreferKey {
     const val bookshelfLayoutGridPortrait = "bookshelfLayoutGridPortrait"
     const val tabletInterface = "tabletInterface"
     const val pureBlack = "pure_black"
+    const val labelVisibilityMode = "labelVisibilityMode"
 }

+ 6 - 0
app/src/main/java/io/legato/kazusa/help/config/AppConfig.kt

@@ -814,5 +814,11 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
         set(value) {
             appCtx.getPrefBoolean(PreferKey.pureBlack, value)
         }
+
+    var labelVisibilityMode
+        get() = appCtx.getPrefString(PreferKey.labelVisibilityMode, "auto")
+        set(value) {
+            appCtx.putPrefString(PreferKey.labelVisibilityMode, value)
+        }
 }
 

+ 6 - 0
app/src/main/java/io/legato/kazusa/help/config/LocalConfig.kt

@@ -41,6 +41,12 @@ by appCtx.getSharedPreferences("local", Context.MODE_PRIVATE) {
             putBoolean("privacyPolicyOk", value)
         }
 
+    var navExtended: Boolean
+        get() = getBoolean("navExtended")
+        set(value) {
+            putBoolean("navExtended", value)
+        }
+
     val readHelpVersionIsLast: Boolean
         get() = isLastVersion(1, "readHelpVersion", "firstRead")
 

+ 0 - 2
app/src/main/java/io/legato/kazusa/ui/config/OtherConfigFragment.kt

@@ -17,7 +17,6 @@ import androidx.preference.ListPreference
 import androidx.preference.Preference
 import com.jeremyliao.liveeventbus.LiveEventBus
 import io.legato.kazusa.R
-import io.legato.kazusa.constant.EventBus
 import io.legato.kazusa.constant.PreferKey
 import io.legato.kazusa.databinding.DialogEditTextBinding
 import io.legato.kazusa.help.AppFreezeMonitor
@@ -205,7 +204,6 @@ class OtherConfigFragment : PreferenceFragment(),
                 setProcessTextEnable(it.getBoolean(key, true))
             }
 
-            PreferKey.showDiscovery, PreferKey.showRss, PreferKey.showBottomView -> postEvent(EventBus.NOTIFY_MAIN, true)
             PreferKey.language -> listView.postDelayed(1000) {
                 appCtx.restart()
             }

+ 3 - 3
app/src/main/java/io/legato/kazusa/ui/config/ThemeConfigFragment.kt

@@ -205,9 +205,9 @@ class ThemeConfigFragment : PreferenceFragmentCompat(),
                 upPreferenceSummary(key, getPrefString(key))
             }
 
-            PreferKey.tabletInterface -> {
-                recreateActivities()
-            }
+            PreferKey.showDiscovery, PreferKey.showRss,
+            PreferKey.showBottomView, PreferKey.tabletInterface,
+            PreferKey.labelVisibilityMode -> postEvent(EventBus.NOTIFY_MAIN, true)
         }
 
     }

+ 51 - 35
app/src/main/java/io/legato/kazusa/ui/main/MainActivity.kt

@@ -20,6 +20,7 @@ import androidx.lifecycle.lifecycleScope
 import androidx.viewpager2.adapter.FragmentStateAdapter
 import androidx.viewpager2.widget.ViewPager2
 import com.google.android.material.bottomnavigation.BottomNavigationView
+import com.google.android.material.bottomnavigation.LabelVisibilityMode
 import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
 import com.google.android.material.navigation.NavigationBarView
 import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback
@@ -48,7 +49,6 @@ import io.legato.kazusa.ui.main.explore.ExploreFragment
 import io.legato.kazusa.ui.main.my.MyFragment
 import io.legato.kazusa.ui.main.rss.RssFragment
 import io.legato.kazusa.ui.widget.dialog.TextDialog
-import io.legato.kazusa.utils.dpToPx
 import io.legato.kazusa.utils.gone
 import io.legato.kazusa.utils.hideSoftInput
 import io.legato.kazusa.utils.observeEvent
@@ -371,42 +371,67 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
             } else {
                 binding.bottomNavigationView.gone()
             }
+
+            navView.labelVisibilityMode = when (AppConfig.labelVisibilityMode) {
+                "auto" -> LabelVisibilityMode.LABEL_VISIBILITY_AUTO
+                "selected" -> LabelVisibilityMode.LABEL_VISIBILITY_SELECTED
+                "labeled" -> LabelVisibilityMode.LABEL_VISIBILITY_LABELED
+                "unlabeled" -> LabelVisibilityMode.LABEL_VISIBILITY_UNLABELED
+                else -> LabelVisibilityMode.LABEL_VISIBILITY_AUTO
+            }
+
         } else {
             binding.bottomNavigationView.gone()
             binding.navigationRailView.gone()
         }
 
+        val lp =
+            binding.navigationRailView.headerView!!.layoutParams as FrameLayout.LayoutParams
+        lp.gravity = Gravity.START
+
+        binding.navigationRailView.headerView!!
+            .setPadding(
+                binding.navigationRailView.itemActiveIndicatorExpandedMarginHorizontal,
+                0,
+                binding.navigationRailView.itemActiveIndicatorExpandedMarginHorizontal,
+                0)
+
         val efab =
-            binding.navigationRailView.headerView?.findViewById<ExtendedFloatingActionButton>(R.id.nav_fab)
-        efab?.let { it.isExtended = false }
+            binding.navigationRailView.headerView!!.findViewById<ExtendedFloatingActionButton>(R.id.nav_fab)
+        val button =
+            binding.navigationRailView.headerView!!.findViewById<ImageView>(R.id.nav_botton)
+
+        efab.let {
+            if (LocalConfig.navExtended) {
+                it.isExtended = true
+                binding.navigationRailView.expand()
+                button.setImageResource(R.drawable.ic_menu_open)
+            } else {
+                it.isExtended = false
+                binding.navigationRailView.collapse()
+                button.setImageResource(R.drawable.ic_menu)
+            }
+        }
 
-        val lp =
-            binding.navigationRailView.headerView?.let { it.layoutParams as FrameLayout.LayoutParams }
-        lp!!.gravity = Gravity.START
-
-        binding.navigationRailView.headerView?.setPadding(
-            12.dpToPx(),
-            12.dpToPx(),
-            12.dpToPx(),
-            12.dpToPx()
-        )
-
-        binding.navigationRailView.headerView?.findViewById<ExtendedFloatingActionButton>(R.id.nav_fab)
-            ?.setOnClickListener {
+        efab.setOnClickListener {
                 startActivity<SearchActivity>()
             }
-        binding.navigationRailView.headerView?.findViewById<ImageView>(R.id.nav_botton)
-            ?.setOnClickListener {
-                efab?.let { it1 ->
-                    if (it1.isExtended) {
-                        efab.isExtended = false
-                        binding.navigationRailView.collapse()
-                    } else {
-                        efab.isExtended = true
-                        binding.navigationRailView.expand()
-                    }
+
+        button.setOnClickListener {
+            efab.let { it1 ->
+                if (it1.isExtended) {
+                    efab.isExtended = false
+                    binding.navigationRailView.collapse()
+                    button.setImageResource(R.drawable.ic_menu)
+                } else {
+                    efab.isExtended = true
+                    binding.navigationRailView.expand()
+                    button.setImageResource(R.drawable.ic_menu_open)
                 }
+                LocalConfig.navExtended = it1.isExtended
             }
+        }
+
     }
 
     private fun bindNavigationListener() {
@@ -419,14 +444,6 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
         }
     }
 
-    private fun updateNavigationRailFab(position: Int) {
-        binding.navigationRailView.headerView?.gone()
-        val fragmentId = getFragmentId(position)
-        if (fragmentId == idBookshelf1 || fragmentId == idBookshelf2 || fragmentId == idBookshelf3) {
-            binding.navigationRailView.headerView?.visible()
-        }
-    }
-
     private fun upHomePage() {
         when (AppConfig.defaultHomePage) {
             "bookshelf" -> {}
@@ -467,7 +484,6 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
                 idMy -> R.id.menu_my_config
                 else -> R.id.menu_bookshelf
             }
-            updateNavigationRailFab(position)
         }
     }
 

+ 3 - 3
app/src/main/java/io/legato/kazusa/ui/main/bookshelf/books/styleDefalut/BooksAdapterList.kt

@@ -31,7 +31,7 @@ class BooksAdapterList(
         item: Book,
         payloads: MutableList<Any>
     ) = binding.run {
-        binding.ivCover.transitionName = "book_${item.bookUrl}"
+        binding.cdCover.transitionName = "book_${item.bookUrl}"
         if (payloads.isEmpty()) {
             tvName.text = item.name
             tvAuthor.text = item.author
@@ -98,13 +98,13 @@ class BooksAdapterList(
         holder.itemView.apply {
             binding.cvContent.setOnClickListener {
                 getItem(holder.layoutPosition)?.let {
-                    callBack.open(it, binding.ivCover)
+                    callBack.open(it, binding.cdCover)
                 }
             }
 
             binding.cvContent.onLongClick {
                 getItem(holder.layoutPosition)?.let {
-                    callBack.openBookInfo(it, binding.ivCover)
+                    callBack.openBookInfo(it, binding.cdCover)
                 }
             }
         }

+ 2 - 2
app/src/main/java/io/legato/kazusa/ui/main/bookshelf/books/styleFold/BooksAdapterList.kt

@@ -113,10 +113,10 @@ class BooksAdapterList(context: Context, callBack: CallBack) :
 
         fun registerListener(item: Any) {
             binding.cvContent.setOnClickListener {
-                callBack.onItemClick(item, binding.ivCover)
+                callBack.onItemClick(item, binding.cdCover)
             }
             binding.cvContent.onLongClick {
-                callBack.onItemLongClick(item, binding.ivCover)
+                callBack.onItemLongClick(item, binding.cdCover)
             }
         }
 

+ 1 - 6
app/src/main/java/io/legato/kazusa/ui/widget/EmptyMessageView.kt

@@ -18,7 +18,7 @@ class EmptyMessageView @JvmOverloads constructor(
     private val messageTextView: TextView
 
     private val faces = listOf(
-        "(๑`^´๑)", "(´・ᴗ・`)", "(•̀ᴗ•́)و", "(ᵔᴥᵔ)", "(¬‿¬)", "(ಥ﹏ಥ)", "(。•́︿•̀。)"
+        "(;′⌒`)", "(つ﹏⊂)", "(•̀ᴗ•́)و", "(๑•́ ₃ •̀๑)", "(눈‸눈)", "(ಥ﹏ಥ)", "(。•́︿•̀。)"
     )
 
     init {
@@ -70,9 +70,4 @@ class EmptyMessageView @JvmOverloads constructor(
         messageTextView.text = msg
     }
 
-
-    /** 可选:手动刷新随机颜文字 */
-    fun refreshFace() {
-        faceTextView.text = faces.random()
-    }
 }

+ 14 - 0
app/src/main/res/drawable/ic_menu_open.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal"
+    android:autoMirrored="true"
+    tools:ignore="NewApi">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M120,720v-80L640,640v80L120,720ZM784,680L584,480L784,280l56,56L696,480L840,624l-56,56ZM120,520v-80L520,440v80L120,520ZM120,320v-80L640,240v80L120,320Z"/>
+</vector>

+ 2 - 1
app/src/main/res/layout/activity_book_search.xml

@@ -175,7 +175,8 @@
                     style="@style/Widget.Material3Expressive.Button"
                     android:text="@string/delete_all"
                     app:backgroundTint="?attr/colorTertiary"
-                    app:iconTint="?attr/colorSurface"
+                    app:iconTint="?attr/colorOnTertiary"
+                    android:textColor="?attr/colorOnTertiary"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     app:icon="@drawable/ic_clear_all"

+ 2 - 4
app/src/main/res/layout/activity_main.xml

@@ -20,10 +20,9 @@
         android:id="@+id/bottom_navigation_view"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:minHeight="56dp"
         android:visibility="visible"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
         app:menu="@menu/main_bnv" />
 
     <com.google.android.material.navigationrail.NavigationRailView
@@ -33,9 +32,8 @@
         android:background="?attr/colorSurfaceContainer"
         android:visibility="visible"
         app:headerLayout="@layout/navigation_rail_fab"
-        app:layout_constraintBottom_toBottomOf="parent"
+        app:expandedMinWidth="0dp"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
         app:menu="@menu/main_bnv"
         app:menuGravity="center" />
 

+ 46 - 49
app/src/main/res/layout/item_bookshelf_grid.xml

@@ -21,21 +21,18 @@
             android:layout_height="wrap_content"
             android:orientation="vertical">
 
-            <androidx.constraintlayout.widget.ConstraintLayout
+            <com.google.android.material.card.MaterialCardView
+                android:id="@+id/cd_cover"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content">
+                android:layout_height="match_parent"
+                app:cardCornerRadius="8dp"
+                android:layout_margin="8dp"
+                android:transitionName="img_cover"
+                app:strokeWidth="0dp">
 
-                <com.google.android.material.card.MaterialCardView
-                    android:id="@+id/cd_cover"
+                <androidx.constraintlayout.widget.ConstraintLayout
                     android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    app:cardCornerRadius="8dp"
-                    app:layout_constraintEnd_toEndOf="parent"
-                    android:layout_margin="8dp"
-                    android:transitionName="img_cover"
-                    app:layout_constraintTop_toTopOf="parent"
-                    app:layout_constraintStart_toStartOf="parent"
-                    app:strokeWidth="0dp">
+                    android:layout_height="wrap_content">
 
                     <io.legato.kazusa.ui.widget.image.CoverImageView
                         android:id="@+id/iv_cover"
@@ -44,49 +41,49 @@
                         android:scaleType="centerCrop"
                         android:src="@drawable/image_cover_default"
                         tools:ignore="ImageContrastCheck" />
-                </com.google.android.material.card.MaterialCardView>
 
+                    <com.google.android.material.progressindicator.LinearProgressIndicator
+                        android:id="@+id/rl_loading"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginVertical="4dp"
+                        android:layout_marginHorizontal="12dp"
+                        android:indeterminate="true"
+                        android:visibility="invisible"
+                        android:layout_gravity="top"
+                        app:layout_constraintEnd_toEndOf="parent"
+                        app:layout_constraintStart_toStartOf="parent"
+                        app:layout_constraintTop_toTopOf="parent" />
 
-                <com.google.android.material.progressindicator.LinearProgressIndicator
-                    android:id="@+id/rl_loading"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginVertical="4dp"
-                    android:layout_marginHorizontal="12dp"
-                    android:indeterminate="true"
-                    android:visibility="invisible"
-                    android:layout_gravity="top"
-                    app:layout_constraintEnd_toEndOf="@id/cd_cover"
-                    app:layout_constraintStart_toStartOf="@id/cd_cover"
-                    app:layout_constraintTop_toTopOf="@id/cd_cover" />
-
-                <com.google.android.material.card.MaterialCardView
-                    android:id="@+id/cd_unread"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_margin="4dp"
-                    android:visibility="visible"
-                    app:cardCornerRadius="4dp"
-                    app:strokeWidth="0dp"
-                    app:cardBackgroundColor="?attr/colorSecondaryVariant"
-                    app:layout_constraintEnd_toEndOf="@id/cd_cover"
-                    app:layout_constraintTop_toTopOf="@id/cd_cover">
-
-                    <TextView
-                        android:id="@+id/tv_unread"
+                    <com.google.android.material.card.MaterialCardView
+                        android:id="@+id/cd_unread"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
-                        android:textColor="?attr/colorSurface"
-                        android:textSize="10sp"
-                        android:padding="4dp"
-                        android:textStyle="bold"
-                        android:includeFontPadding="false"
-                        tools:text="5"
-                        tools:ignore="SmallSp" />
+                        android:layout_margin="4dp"
+                        android:visibility="visible"
+                        app:cardCornerRadius="4dp"
+                        app:strokeWidth="0dp"
+                        app:cardBackgroundColor="?attr/colorSecondaryVariant"
+                        app:layout_constraintEnd_toEndOf="parent"
+                        app:layout_constraintTop_toTopOf="parent">
+
+                        <TextView
+                            android:id="@+id/tv_unread"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:textColor="?attr/colorSurface"
+                            android:textSize="10sp"
+                            android:padding="4dp"
+                            android:textStyle="bold"
+                            android:includeFontPadding="false"
+                            tools:text="5"
+                            tools:ignore="SmallSp" />
+
+                    </com.google.android.material.card.MaterialCardView>
 
-                </com.google.android.material.card.MaterialCardView>
+                </androidx.constraintlayout.widget.ConstraintLayout>
 
-            </androidx.constraintlayout.widget.ConstraintLayout>
+            </com.google.android.material.card.MaterialCardView>
 
             <!-- 书名 -->
             <TextView

+ 65 - 57
app/src/main/res/layout/item_bookshelf_list.xml

@@ -16,68 +16,76 @@
         android:background="?attr/selectableItemBackground"
         tools:ignore="UnusedAttribute">
 
-        <androidx.constraintlayout.widget.ConstraintLayout
-            android:id="@+id/cl_cover"
-            android:layout_width="70dp"
-            android:layout_height="98dp"
-            android:layout_marginStart="8dp"
-            android:layout_marginVertical="8dp"
+        <com.google.android.material.card.MaterialCardView
+            android:id="@+id/cd_cover"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:cardCornerRadius="8dp"
+            app:strokeWidth="0dp"
+            android:layout_margin="8dp"
+            android:transitionName="img_cover"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent"
             app:layout_constraintBottom_toBottomOf="parent">
-            <!-- 书封面 -->
-            <io.legato.kazusa.ui.widget.image.CoverImageView
-                android:id="@+id/iv_cover"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:scaleType="centerCrop"
-                android:src="@drawable/image_cover_default"
-                android:transitionName="img_cover"
-                app:layout_constraintTop_toTopOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                tools:ignore="ImageContrastCheck" />
-
-            <com.google.android.material.progressindicator.LinearProgressIndicator
-                android:id="@+id/rl_loading"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginVertical="4dp"
-                android:layout_marginHorizontal="6dp"
-                android:indeterminate="true"
-                android:visibility="invisible"
-                android:layout_gravity="top"
-                app:layout_constraintTop_toTopOf="@id/iv_cover"
-                app:layout_constraintStart_toStartOf="@id/iv_cover"
-                app:layout_constraintEnd_toEndOf="@id/iv_cover" />
-
-            <com.google.android.material.card.MaterialCardView
-                android:id="@+id/cd_unread"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_margin="4dp"
-                android:visibility="visible"
-                app:cardCornerRadius="4dp"
-                app:strokeWidth="0dp"
-                app:cardBackgroundColor="?attr/colorSecondaryVariant"
-                app:layout_constraintTop_toTopOf="@id/iv_cover"
-                app:layout_constraintEnd_toEndOf="@id/iv_cover">
-
-                <TextView
-                    android:id="@+id/tv_unread"
+            <androidx.constraintlayout.widget.ConstraintLayout
+                android:id="@+id/cl_cover"
+                android:layout_width="70dp"
+                android:layout_height="98dp">
+
+                <io.legato.kazusa.ui.widget.image.CoverImageView
+                    android:id="@+id/iv_cover"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:scaleType="centerCrop"
+                    android:src="@drawable/image_cover_default"
+                    app:layout_constraintTop_toTopOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    tools:ignore="ImageContrastCheck" />
+
+                <com.google.android.material.progressindicator.LinearProgressIndicator
+                    android:id="@+id/rl_loading"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginVertical="4dp"
+                    android:layout_marginHorizontal="6dp"
+                    android:indeterminate="true"
+                    android:visibility="invisible"
+                    android:layout_gravity="top"
+                    app:layout_constraintTop_toTopOf="@id/iv_cover"
+                    app:layout_constraintStart_toStartOf="@id/iv_cover"
+                    app:layout_constraintEnd_toEndOf="@id/iv_cover" />
+
+                <com.google.android.material.card.MaterialCardView
+                    android:id="@+id/cd_unread"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:textColor="?attr/colorSurface"
-                    android:textSize="10sp"
-                    android:padding="4dp"
-                    android:textStyle="bold"
-                    android:includeFontPadding="false"
-                    tools:text="5"
-                    tools:ignore="SmallSp" />
+                    android:layout_margin="4dp"
+                    android:visibility="visible"
+                    app:cardCornerRadius="4dp"
+                    app:strokeWidth="0dp"
+                    app:cardBackgroundColor="?attr/colorSecondaryVariant"
+                    app:layout_constraintTop_toTopOf="@id/iv_cover"
+                    app:layout_constraintEnd_toEndOf="@id/iv_cover">
+
+                    <TextView
+                        android:id="@+id/tv_unread"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:textColor="?attr/colorSurface"
+                        android:textSize="10sp"
+                        android:padding="4dp"
+                        android:textStyle="bold"
+                        android:includeFontPadding="false"
+                        tools:text="5"
+                        tools:ignore="SmallSp" />
+
+                </com.google.android.material.card.MaterialCardView>
+
+            </androidx.constraintlayout.widget.ConstraintLayout>
+        </com.google.android.material.card.MaterialCardView>
 
-            </com.google.android.material.card.MaterialCardView>
 
-        </androidx.constraintlayout.widget.ConstraintLayout>
 
         <TextView
             android:id="@+id/tv_name"
@@ -90,9 +98,9 @@
             android:text="@string/book_name"
             style="@style/ChapterNameText"
             tools:ignore="RtlHardcoded,RtlSymmetry"
-            app:layout_constraintStart_toEndOf="@+id/cl_cover"
+            app:layout_constraintStart_toEndOf="@+id/cd_cover"
             app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="@id/cl_cover" />
+            app:layout_constraintTop_toTopOf="@id/cd_cover" />
 
         <androidx.appcompat.widget.AppCompatImageView
             android:id="@+id/iv_author"

+ 3 - 3
app/src/main/res/layout/item_fillet_text.xml

@@ -3,8 +3,8 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    app:cardBackgroundColor="?attr/colorTertiaryFixed"
-    app:strokeColor="?attr/colorTertiaryFixed"
+    app:cardBackgroundColor="?attr/colorTertiaryContainer"
+    app:strokeColor="?attr/colorTertiaryContainer"
     android:clickable="true"
     android:focusable="true">
     <TextView
@@ -20,7 +20,7 @@
         android:paddingEnd="16dp"
         android:maxLines="1"
         android:textSize="14sp"
-        android:textColor="?attr/colorOnTertiaryFixedVariant"
+        android:textColor="?attr/colorOnTertiaryContainer"
         tools:ignore="UnusedAttribute" />
 </com.google.android.material.card.MaterialCardView>
 

+ 7 - 1
app/src/main/res/layout/navigation_rail_fab.xml

@@ -2,7 +2,7 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/navigation_rail_fab"
-    android:layout_width="match_parent"
+    android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_gravity="top|start"
     android:clipChildren="false"
@@ -13,6 +13,7 @@
         android:id="@+id/nav_botton"
         android:layout_width="56dp"
         android:layout_height="56dp"
+        android:background="?attr/selectableItemBackgroundBorderless"
         android:scaleType="center"
         android:src="@drawable/ic_menu" />
 
@@ -20,6 +21,11 @@
         android:id="@+id/nav_fab"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:backgroundTint="?attr/colorTertiaryContainer"
+        app:iconTint="?attr/colorOnTertiaryContainer"
+        android:textColor="?attr/colorOnTertiaryContainer"
+        android:minWidth="0dp"
+        android:scrollbars="none"
         android:text="@string/search"
         app:icon="@drawable/ic_search" />
 

+ 2 - 0
app/src/main/res/values-night/themes.xml

@@ -10,6 +10,8 @@
         <item name="chipStyle">@style/Widget.MyApp.Chip.Assist</item>
         <item name="popupMenuBackground">@drawable/popup_background</item>
         <item name="alertDialogTheme">@style/AppTheme.AlertDialog</item>
+        <item name="navigationRailStyle">@style/Widget.Material3Expressive.NavigationRailView</item>
+        <item name="bottomNavigationStyle">@style/Widget.Material3Expressive.BottomNavigationView</item>
     </style>
 
     <style name="ThemeOverlay.WhiteBackground" parent="">

+ 7 - 0
app/src/main/res/values-zh/arrays.xml

@@ -136,4 +136,11 @@
         <item>仅强调色</item>
     </string-array>
 
+    <string-array name="label_vis_mode" >
+        <item>自动</item>
+        <item>选中时显示</item>
+        <item>常驻</item>
+        <item>不显示</item>
+    </string-array>
+
 </resources>

+ 7 - 0
app/src/main/res/values/array_values.xml

@@ -81,4 +81,11 @@
         <item>accent</item>
     </string-array>
 
+    <string-array name="label_vis_mode_value">
+        <item>auto</item>
+        <item>selected</item>
+        <item>labeled</item>
+        <item>unlabeled</item>
+    </string-array>
+
 </resources>

+ 7 - 0
app/src/main/res/values/arrays.xml

@@ -222,4 +222,11 @@
 		<item>@string/bookshelf_px_5</item>
 	</string-array>
 
+    <string-array name="label_vis_mode" >
+		<item>Auto</item>
+		<item>Selected</item>
+		<item>Labeled</item>
+		<item>Unlabeled</item>
+	</string-array>
+
 </resources>

+ 0 - 3
app/src/main/res/values/dimens.xml

@@ -4,7 +4,6 @@
     <dimen name="activity_vertical_margin">16dp</dimen>
     <dimen name="nav_header_vertical_spacing">8dp</dimen>
     <dimen name="nav_header_height">176dp</dimen>
-    <dimen name="fab_margin">16dp</dimen>
 
     <dimen name="font_size_normal">14sp</dimen>
     <dimen name="font_size_middle">16sp</dimen>
@@ -17,8 +16,6 @@
 
     <dimen name="desc_icon_size">18sp</dimen>
 
-    <dimen name="toolbar_elevation">4dp</dimen>
-
     <dimen name="fastscroll_bubble_radius">44dp</dimen>
     <dimen name="fastscroll_bubble_size">88dp</dimen>
     <dimen name="fastscroll_bubble_textsize">48sp</dimen>

+ 2 - 0
app/src/main/res/values/themes.xml

@@ -9,6 +9,8 @@
         <item name="chipStyle">@style/Widget.MyApp.Chip.Assist</item>
         <item name="popupMenuBackground">@drawable/popup_background</item>
         <item name="alertDialogTheme">@style/AppTheme.AlertDialog</item>
+        <item name="navigationRailStyle">@style/Widget.Material3Expressive.NavigationRailView</item>
+        <item name="bottomNavigationStyle">@style/Widget.Material3Expressive.BottomNavigationView</item>
     </style>
 
     <style name="ThemeOverlay.WhiteBackground" parent="">

+ 70 - 78
app/src/main/res/xml/pref_config_other.xml

@@ -28,40 +28,15 @@
             android:key="defaultToRead"
             android:summary="@string/ps_default_read"
             android:title="@string/pt_default_read"
-            app:iconSpaceReserved="false" />
-
-        <io.legato.kazusa.lib.prefs.SwitchPreference
-            android:defaultValue="true"
-            android:key="showDiscovery"
-            android:title="@string/show_discovery"
-            app:iconSpaceReserved="false" />
-
-        <io.legato.kazusa.lib.prefs.SwitchPreference
-            android:defaultValue="true"
-            android:key="showRss"
-            android:title="@string/show_rss"
-            app:iconSpaceReserved="false" />
-
-        <io.legato.kazusa.lib.prefs.SwitchPreference
-            android:defaultValue="true"
-            android:key="showBottomView"
-            android:summary="仍可滑动切换页面"
-            android:title="显示底部导航栏"
-            app:iconSpaceReserved="false" />
-
-        <io.legato.kazusa.lib.prefs.NameListPreference
-            android:defaultValue="bookshelf"
-            android:key="defaultHomePage"
-            android:title="@string/default_home_page"
             app:allowDividerAbove="false"
             app:allowDividerBelow="false"
-            app:entries="@array/default_home_page"
-            app:entryValues="@array/default_home_page_value" />
+            app:iconSpaceReserved="false" />
 
     </io.legato.kazusa.lib.prefs.PreferenceCategory>
 
     <io.legato.kazusa.lib.prefs.PreferenceCategory
-        android:title="@string/other_setting"
+        android:title="隐私"
+        app:allowDividerAbove="false"
         app:allowDividerBelow="false"
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
@@ -78,73 +53,30 @@
             android:summary="@string/ignore_battery_permission_rationale"
             android:title="后台权限" />
 
-        <io.legato.kazusa.lib.prefs.NameListPreference
-            android:defaultValue="official_version"
-            android:key="updateToVariant"
-            android:summary="@string/update_to_variant_summary"
-            android:title="@string/update_to_variant_title"
-            app:allowDividerAbove="false"
-            app:allowDividerBelow="false"
-            app:entries="@array/default_app_variant"
-            app:entryValues="@array/default_app_variant_value" />
-
         <io.legato.kazusa.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:key="firebaseEnable"
             android:summary="@string/firebase_enable_summary"
             android:title="@string/firebase_enable_title" />
 
-        <io.legato.kazusa.lib.prefs.SwitchPreference
-            android:defaultValue="true"
-            android:key="sharedElementEnterTransitionEnable"
-            android:summary="从书架进入阅读界面时,优化动画效果。"
-            android:title="使用共享元素动画" />
-
-        <io.legato.kazusa.lib.prefs.SwitchPreference
-            android:defaultValue="true"
-            android:key="delayBookLoadEnable"
-            android:summary="减少进入阅读界面时的卡顿,但加载书籍时间会延长。"
-            android:title="延缓书籍加载" />
-
         <io.legato.kazusa.lib.prefs.Preference
             android:key="localPassword"
             android:summary="@string/set_local_password_summary"
             android:title="@string/set_local_password" />
 
-        <io.legato.kazusa.lib.prefs.Preference
-            android:key="userAgent"
-            android:title="@string/user_agent" />
+    </io.legato.kazusa.lib.prefs.PreferenceCategory>
 
-        <io.legato.kazusa.lib.prefs.SwitchPreference
-            android:defaultValue="false"
-            android:key="webServiceWakeLock"
-            android:summary="@string/web_service_wake_lock_summary"
-            android:title="@string/web_service_wake_lock" />
+    <io.legato.kazusa.lib.prefs.PreferenceCategory
+        android:title="阅读"
+        app:allowDividerBelow="false"
+        app:iconSpaceReserved="false"
+        app:layout="@layout/view_preference_category">
 
         <io.legato.kazusa.lib.prefs.Preference
             android:key="defaultBookTreeUri"
             android:summary="@string/book_tree_uri_s"
             android:title="@string/book_tree_uri_t" />
 
-        <io.legato.kazusa.lib.prefs.Preference
-            android:key="sourceEditMaxLine"
-            android:title="@string/source_edit_text_max_line" />
-
-        <io.legato.kazusa.lib.prefs.Preference
-            android:key="checkSource"
-            android:title="@string/check_source_config" />
-
-        <io.legato.kazusa.lib.prefs.Preference
-            android:key="uploadRule"
-            android:summary="@string/direct_link_upload_rule_summary"
-            android:title="@string/direct_link_upload_rule" />
-
-        <io.legato.kazusa.lib.prefs.SwitchPreference
-            android:defaultValue="false"
-            android:key="Cronet"
-            android:summary="@string/pref_cronet_summary"
-            android:title="Cronet" />
-
         <io.legato.kazusa.lib.prefs.SwitchPreference
             android:defaultValue="false"
             android:key="antiAlias"
@@ -211,6 +143,67 @@
             android:title="@string/show_manga_ui"
             app:iconSpaceReserved="false" />
 
+    </io.legato.kazusa.lib.prefs.PreferenceCategory>
+
+    <io.legato.kazusa.lib.prefs.PreferenceCategory
+        android:title="@string/other_setting"
+        app:allowDividerBelow="false"
+        app:iconSpaceReserved="false"
+        app:layout="@layout/view_preference_category">
+
+        <io.legato.kazusa.lib.prefs.NameListPreference
+            android:defaultValue="official_version"
+            android:key="updateToVariant"
+            android:summary="@string/update_to_variant_summary"
+            android:title="@string/update_to_variant_title"
+            app:allowDividerAbove="false"
+            app:allowDividerBelow="false"
+            app:entries="@array/default_app_variant"
+            app:entryValues="@array/default_app_variant_value" />
+
+
+
+        <io.legato.kazusa.lib.prefs.SwitchPreference
+            android:defaultValue="true"
+            android:key="sharedElementEnterTransitionEnable"
+            android:summary="从书架进入阅读界面时,优化动画效果。"
+            android:title="使用共享元素动画" />
+
+        <io.legato.kazusa.lib.prefs.SwitchPreference
+            android:defaultValue="true"
+            android:key="delayBookLoadEnable"
+            android:summary="减少进入阅读界面时的卡顿,但加载书籍时间会延长。"
+            android:title="延缓书籍加载" />
+
+        <io.legato.kazusa.lib.prefs.Preference
+            android:key="userAgent"
+            android:title="@string/user_agent" />
+
+        <io.legato.kazusa.lib.prefs.SwitchPreference
+            android:defaultValue="false"
+            android:key="webServiceWakeLock"
+            android:summary="@string/web_service_wake_lock_summary"
+            android:title="@string/web_service_wake_lock" />
+
+        <io.legato.kazusa.lib.prefs.Preference
+            android:key="sourceEditMaxLine"
+            android:title="@string/source_edit_text_max_line" />
+
+        <io.legato.kazusa.lib.prefs.Preference
+            android:key="checkSource"
+            android:title="@string/check_source_config" />
+
+        <io.legato.kazusa.lib.prefs.Preference
+            android:key="uploadRule"
+            android:summary="@string/direct_link_upload_rule_summary"
+            android:title="@string/direct_link_upload_rule" />
+
+        <io.legato.kazusa.lib.prefs.SwitchPreference
+            android:defaultValue="false"
+            android:key="Cronet"
+            android:summary="@string/pref_cronet_summary"
+            android:title="Cronet" />
+
         <io.legato.kazusa.lib.prefs.Preference
             android:key="webPort"
             android:title="@string/web_port_title"
@@ -262,5 +255,4 @@
 
     </io.legato.kazusa.lib.prefs.PreferenceCategory>
 
-
 </androidx.preference.PreferenceScreen>

+ 53 - 7
app/src/main/res/xml/pref_config_theme.xml

@@ -60,13 +60,6 @@
             app:iconSpaceReserved="false"
             app:icons="@array/icons" />
 
-        <io.legato.kazusa.lib.prefs.NameListPreference
-            android:defaultValue="auto"
-            android:key="tabletInterface"
-            android:title="@string/tabletInterface"
-            app:entries="@array/tabletInterface"
-            app:entryValues="@array/tabletInterface_value" />
-
         <io.legato.kazusa.lib.prefs.Preference
             android:key="fontScale"
             android:summary="@string/font_scale_summary"
@@ -83,6 +76,59 @@
 
     </io.legato.kazusa.lib.prefs.PreferenceCategory>
 
+    <io.legato.kazusa.lib.prefs.PreferenceCategory
+        android:title="@string/main_activity"
+        app:allowDividerAbove="false"
+        app:allowDividerBelow="false"
+        app:iconSpaceReserved="false"
+        app:layout="@layout/view_preference_category">
+
+        <io.legato.kazusa.lib.prefs.SwitchPreference
+            android:defaultValue="true"
+            android:key="showDiscovery"
+            android:title="@string/show_discovery"
+            app:iconSpaceReserved="false" />
+
+        <io.legato.kazusa.lib.prefs.SwitchPreference
+            android:defaultValue="true"
+            android:key="showRss"
+            android:title="@string/show_rss"
+            app:iconSpaceReserved="false" />
+
+        <io.legato.kazusa.lib.prefs.SwitchPreference
+            android:defaultValue="true"
+            android:key="showBottomView"
+            android:summary="仍可滑动切换页面"
+            android:title="显示底部导航栏"
+            app:iconSpaceReserved="false" />
+
+        <io.legato.kazusa.lib.prefs.NameListPreference
+            android:defaultValue="auto"
+            android:key="tabletInterface"
+            android:title="@string/tabletInterface"
+            app:entries="@array/tabletInterface"
+            app:entryValues="@array/tabletInterface_value" />
+
+        <io.legato.kazusa.lib.prefs.NameListPreference
+            android:defaultValue="auto"
+            android:key="labelVisibilityMode"
+            android:title="导航栏标签显示方式"
+            app:allowDividerAbove="false"
+            app:allowDividerBelow="false"
+            app:entries="@array/label_vis_mode"
+            app:entryValues="@array/label_vis_mode_value" />
+
+        <io.legato.kazusa.lib.prefs.NameListPreference
+            android:defaultValue="bookshelf"
+            android:key="defaultHomePage"
+            android:title="@string/default_home_page"
+            app:allowDividerAbove="false"
+            app:allowDividerBelow="false"
+            app:entries="@array/default_home_page"
+            app:entryValues="@array/default_home_page_value" />
+
+    </io.legato.kazusa.lib.prefs.PreferenceCategory>
+
     <io.legato.kazusa.lib.prefs.PreferenceCategory
         android:key="backgroundIma"
         android:title="@string/background_image"