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

增加漫画单独配置
更新界面

HapeLee 1 год назад
Родитель
Сommit
3c5df88027
44 измененных файлов с 760 добавлено и 1021 удалено
  1. 1 0
      app/src/main/java/io/legato/kazusa/constant/PreferKey.kt
  2. 4 1
      app/src/main/java/io/legato/kazusa/data/entities/Book.kt
  3. 10 6
      app/src/main/java/io/legato/kazusa/help/config/AppConfig.kt
  4. 30 6
      app/src/main/java/io/legato/kazusa/ui/book/group/GroupEditDialog.kt
  5. 34 18
      app/src/main/java/io/legato/kazusa/ui/book/manga/ReadMangaActivity.kt
  6. 24 0
      app/src/main/java/io/legato/kazusa/ui/book/manga/ReadMangaViewModel.kt
  7. 13 2
      app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaScrollModeDialog.kt
  8. 20 16
      app/src/main/java/io/legato/kazusa/ui/book/read/config/ReadStyleDialog.kt
  9. 6 6
      app/src/main/java/io/legato/kazusa/ui/book/source/manage/BookSourceAdapter.kt
  10. 0 445
      app/src/main/java/io/legato/kazusa/ui/widget/image/CircleImageView.kt
  11. 5 6
      app/src/main/res/layout-land/activity_book_info.xml
  12. 1 1
      app/src/main/res/layout/activity_audio_play.xml
  13. 10 12
      app/src/main/res/layout/activity_book_info.xml
  14. 3 3
      app/src/main/res/layout/activity_book_info_edit.xml
  15. 4 7
      app/src/main/res/layout/activity_manga.xml
  16. 29 38
      app/src/main/res/layout/dialog_auto_read.xml
  17. 34 24
      app/src/main/res/layout/dialog_book_group_edit.xml
  18. 3 3
      app/src/main/res/layout/dialog_bookmark.xml
  19. 174 168
      app/src/main/res/layout/dialog_bookshelf_config.xml
  20. 8 10
      app/src/main/res/layout/dialog_check_source_config.xml
  21. 3 3
      app/src/main/res/layout/dialog_cover_rule_config.xml
  22. 7 12
      app/src/main/res/layout/dialog_dict.xml
  23. 3 3
      app/src/main/res/layout/dialog_direct_link_upload_config.xml
  24. 1 1
      app/src/main/res/layout/dialog_file_chooser.xml
  25. 2 2
      app/src/main/res/layout/dialog_manga_footer_setting.xml
  26. 13 9
      app/src/main/res/layout/dialog_manga_scroll_mode.xml
  27. 2 2
      app/src/main/res/layout/dialog_open_url_confirm.xml
  28. 87 73
      app/src/main/res/layout/dialog_read_bg_text.xml
  29. 22 15
      app/src/main/res/layout/dialog_read_book_style.xml
  30. 3 3
      app/src/main/res/layout/dialog_recycler_view.xml
  31. 3 3
      app/src/main/res/layout/dialog_update.xml
  32. 1 1
      app/src/main/res/layout/item_arrange_book.xml
  33. 15 7
      app/src/main/res/layout/item_bg_image.xml
  34. 1 1
      app/src/main/res/layout/item_book_group_manage.xml
  35. 10 10
      app/src/main/res/layout/item_book_source.xml
  36. 0 1
      app/src/main/res/layout/item_bookshelf_grid.xml
  37. 1 1
      app/src/main/res/layout/item_bookshelf_list.xml
  38. 1 1
      app/src/main/res/layout/item_download.xml
  39. 36 9
      app/src/main/res/layout/item_read_style.xml
  40. 46 23
      app/src/main/res/layout/item_search.xml
  41. 23 8
      app/src/main/res/layout/view_manga_menu.xml
  42. 5 1
      app/src/main/res/values-zh/strings.xml
  43. 6 0
      app/src/main/res/values/strings.xml
  44. 56 60
      app/src/main/res/values/themes.xml

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

@@ -192,6 +192,7 @@ object PreferKey {
     const val showBottomView = "showBottomView"
     const val mangaScrollMode = "mangaScrollMode"
     const val webtoonSidePaddingDp = "webtoonSidePaddingDp"
+    const val mangaVolumeKeyPage = "mangaVolumeKeyPage"
 
     const val mangaClickActionTL = "mangaClickActionTopLeft"
     const val mangaClickActionTC = "mangaClickActionTopCenter"

+ 4 - 1
app/src/main/java/io/legato/kazusa/data/entities/Book.kt

@@ -402,8 +402,11 @@ data class Book(
         var readSimulating: Boolean = false,
         var startDate: LocalDate? = null,
         var startChapter: Int? = null,     // 用户设置的起始章节
-        var dailyChapters: Int = 3    // 用户设置的每日更新章节数
+        var dailyChapters: Int = 3,    // 用户设置的每日更新章节数
 
+        val mangaColorFilter: String? = null,
+        var mangaScrollMode: Int? = null,
+        var webtoonSidePaddingDp: Int? = null
 
     ) : Parcelable
 

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

@@ -743,29 +743,33 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
             appCtx.putPrefBoolean(PreferKey.enableMangaEInk, value)
         }
 
+    //墨水屏阈值
     var mangaEInkThreshold
         get() = appCtx.getPrefInt(PreferKey.mangaEInkThreshold, 150)
         set(value) {
             appCtx.putPrefInt(PreferKey.mangaEInkThreshold, value)
         }
 
-    var disableHorizontalAnimator
-        get() = appCtx.getPrefBoolean(PreferKey.disableHorizontalAnimator, false)
-        set(value) {
-            appCtx.putPrefBoolean(PreferKey.disableHorizontalAnimator, value)
-        }
-
+    //漫画灰度
     var enableMangaGray
         get() = appCtx.getPrefBoolean(PreferKey.enableMangaGray, false)
         set(value) {
             appCtx.putPrefBoolean(PreferKey.enableMangaGray, value)
         }
 
+    //条漫侧边距
     var webtoonSidePaddingDp: Int
         get() = appCtx.getPrefInt(PreferKey.webtoonSidePaddingDp, 0)
         set(value) {
             appCtx.putPrefInt(PreferKey.webtoonSidePaddingDp, value)
         }
 
+    //漫画音量键翻页
+    var MangaVolumeKeyPage: Boolean
+        get() = appCtx.getPrefBoolean(PreferKey.mangaVolumeKeyPage, false)
+        set(value) {
+            appCtx.putPrefBoolean(PreferKey.mangaVolumeKeyPage, value)
+        }
+
 }
 

+ 30 - 6
app/src/main/java/io/legato/kazusa/ui/book/group/GroupEditDialog.kt

@@ -1,14 +1,15 @@
 package io.legato.kazusa.ui.book.group
 
+//import io.legado.app.lib.theme.primaryColor
 import android.os.Bundle
 import android.view.View
+import androidx.appcompat.widget.PopupMenu
 import androidx.fragment.app.viewModels
 import io.legato.kazusa.R
 import io.legato.kazusa.base.BaseBottomSheetDialogFragment
 import io.legato.kazusa.data.entities.BookGroup
 import io.legato.kazusa.databinding.DialogBookGroupEditBinding
 import io.legato.kazusa.lib.dialogs.alert
-//import io.legado.app.lib.theme.primaryColor
 import io.legato.kazusa.utils.FileUtils
 import io.legato.kazusa.utils.MD5Utils
 import io.legato.kazusa.utils.SelectImageContract
@@ -19,7 +20,6 @@ import io.legato.kazusa.utils.launch
 import io.legato.kazusa.utils.readUri
 import io.legato.kazusa.utils.toastOnUi
 import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
-import io.legato.kazusa.utils.visible
 import splitties.init.appCtx
 import splitties.views.onClick
 import java.io.FileOutputStream
@@ -32,6 +32,9 @@ class GroupEditDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_book_gro
         }
     }
 
+    private var selectedSortIndex = -1
+    private lateinit var sortOptions: List<String>
+
     private val binding by viewBinding(DialogBookGroupEditBinding::bind)
     private val viewModel by viewModels<GroupViewModel>()
     private var bookGroup: BookGroup? = null
@@ -62,21 +65,40 @@ class GroupEditDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_book_gro
 
     override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
         //binding.toolBar.setBackgroundColor(primaryColor)
+        sortOptions = resources.getStringArray(R.array.book_sort).toList()
+
         @Suppress("DEPRECATION")
         bookGroup = arguments?.getParcelable("group")
         bookGroup?.let {
-            binding.btnDelete.visible(it.groupId > 0 || it.groupId == Long.MIN_VALUE)
+            binding.btnDelete.isEnabled = (it.groupId > 0 || it.groupId == Long.MIN_VALUE)
             binding.tieGroupName.setText(it.groupName)
             if (bookGroup?.cover != null)
                 binding.ivCover.load(it.cover)
-            binding.spSort.setSelection(it.bookSort + 1)
             binding.cbEnableRefresh.isChecked = it.enableRefresh
+            if (it.bookSort in sortOptions.indices) {
+                selectedSortIndex = it.bookSort
+                binding.chipSortMenu.text = sortOptions[selectedSortIndex]
+            }
         } ?: let {
-            binding.toolBar.title = getString(R.string.add_group)
             binding.btnDelete.gone()
             binding.ivCover.load()
         }
+
         binding.run {
+            chipSortMenu.setOnClickListener { chip ->
+                PopupMenu(requireContext(), chip).apply {
+                    sortOptions.forEachIndexed { index, title ->
+                        menu.add(0, index, index, title)
+                    }
+                    setOnMenuItemClickListener { item ->
+                        selectedSortIndex = item.itemId
+                        chipSortMenu.text = sortOptions[selectedSortIndex]
+                        true
+                    }
+                    show()
+                }
+            }
+
             ivCover.onClick {
                 selectImage.launch()
             }
@@ -88,15 +110,17 @@ class GroupEditDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_book_gro
                     }
                 }
             }
+
             btnCancel.onClick {
                 dismiss()
             }
+
             btnOk.onClick {
                 val groupName = tieGroupName.text?.toString()
                 if (groupName.isNullOrEmpty()) {
                     toastOnUi("分组名称不能为空")
                 } else {
-                    val bookSort = binding.spSort.selectedItemPosition - 1
+                    val bookSort = selectedSortIndex
                     val coverPath = binding.ivCover.bitmapPath
                     val enableRefresh = binding.cbEnableRefresh.isChecked
                     bookGroup?.let {

+ 34 - 18
app/src/main/java/io/legato/kazusa/ui/book/manga/ReadMangaActivity.kt

@@ -4,7 +4,6 @@ import android.annotation.SuppressLint
 import android.content.Intent
 import android.os.Build
 import android.os.Bundle
-import android.os.Looper
 import android.view.KeyEvent
 import android.view.Menu
 import android.view.MenuItem
@@ -202,8 +201,12 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
             enableMangaEInk(AppConfig.enableMangaEInk, AppConfig.mangaEInkThreshold)
             enableGray(AppConfig.enableMangaGray)
         }
-        //setHorizontalScroll(AppConfig.enableMangaHorizontalScroll)
-        setScrollMode(AppConfig.mangaScrollMode)
+
+        viewModel.initData(intent) {
+            setScrollMode(viewModel.getEffectiveScrollMode())
+            updateWebtoonSidePadding(viewModel.getEffectiveWebtoonSidePadding())
+        }
+
         binding.recyclerView.run {
             adapter = mAdapter
             itemAnimator = null
@@ -212,7 +215,6 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
             setDisableClickScroll(AppConfig.disableClickScroll)
             setDisableMangaScale(AppConfig.disableMangaScale)
             setRecyclerViewPreloader(AppConfig.mangaPreDownloadNum)
-            updateWebtoonSidePadding(AppConfig.webtoonSidePaddingDp)
             setPreScrollListener { _, _, _, position ->
                 if (mAdapter.isNotEmpty()) {
                     val item = mAdapter.getItem(position)
@@ -267,10 +269,10 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
 
     override fun onPostCreate(savedInstanceState: Bundle?) {
         super.onPostCreate(savedInstanceState)
-        Looper.myQueue().addIdleHandler {
-            viewModel.initData(intent)
-            false
-        }
+//        Looper.myQueue().addIdleHandler {
+//            viewModel.initData(intent)
+//            false
+//        }
         justInitData = true
     }
 
@@ -563,6 +565,8 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
 
     override fun showScrollModeDialog() {
         showDialogFragment(MangaScrollModeDialog().apply {
+            initialScrollMode = viewModel.getEffectiveScrollMode()
+            initialWebtoonSidePadding = viewModel.getEffectiveWebtoonSidePadding()
             initialAutoPageEnabled = enableScroll
             callback = this@ReadMangaActivity
         })
@@ -570,7 +574,10 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
 
     //漫画模式
     override fun onScrollModeChanged(mode: Int) {
-        AppConfig.mangaScrollMode = mode
+        //AppConfig.mangaScrollMode = mode
+        viewModel.updateReadConfig {
+            mangaScrollMode = mode
+        }
         setScrollMode(mode)
         updateWebtoonSidePadding(AppConfig.webtoonSidePaddingDp)
         setAutoReadEnabled(false)
@@ -590,7 +597,9 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
 
     //侧边留白
     override fun upSidePadding(paddingDp: Int) {
-        AppConfig.webtoonSidePaddingDp = paddingDp
+        viewModel.updateReadConfig {
+            webtoonSidePaddingDp = paddingDp
+        }
         updateWebtoonSidePadding(paddingDp)
     }
 
@@ -626,6 +635,10 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
 //        }
     }
 
+    override fun onVolumeKeyPageChanged(enable: Boolean) {
+        AppConfig.MangaVolumeKeyPage = enable
+    }
+
     override fun onHideMangaTitleChanged(hide: Boolean) {
         AppConfig.hideMangaTitle = hide
         ReadManga.loadContent()
@@ -907,17 +920,20 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
     }
 
     override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
-        when (keyCode) {
-            KeyEvent.KEYCODE_VOLUME_UP -> {
-                scrollToPrev()
-                return true
-            }
+        if (AppConfig.MangaVolumeKeyPage) {
+            when (keyCode) {
+                KeyEvent.KEYCODE_VOLUME_UP -> {
+                    scrollToPrev()
+                    return true
+                }
 
-            KeyEvent.KEYCODE_VOLUME_DOWN -> {
-                scrollToNext()
-                return true
+                KeyEvent.KEYCODE_VOLUME_DOWN -> {
+                    scrollToNext()
+                    return true
+                }
             }
         }
+
         return super.onKeyDown(keyCode, event)
     }
 

+ 24 - 0
app/src/main/java/io/legato/kazusa/ui/book/manga/ReadMangaViewModel.kt

@@ -9,6 +9,7 @@ import io.legato.kazusa.constant.BookType
 import io.legato.kazusa.constant.EventBus
 import io.legato.kazusa.data.appDb
 import io.legato.kazusa.data.entities.Book
+import io.legato.kazusa.data.entities.Book.ReadConfig
 import io.legato.kazusa.data.entities.BookChapter
 import io.legato.kazusa.data.entities.BookProgress
 import io.legato.kazusa.exception.NoStackTraceException
@@ -273,6 +274,29 @@ class ReadMangaViewModel(application: Application) : BaseViewModel(application)
         }
     }
 
+
+    fun getEffectiveScrollMode(): Int {
+        return ReadManga.book?.readConfig?.mangaScrollMode ?: AppConfig.mangaScrollMode
+    }
+
+    fun getEffectiveWebtoonSidePadding(): Int {
+        return ReadManga.book?.readConfig?.webtoonSidePaddingDp ?: AppConfig.webtoonSidePaddingDp
+    }
+
+
+    fun updateReadConfig(update: ReadConfig.() -> Unit) {
+        val book = ReadManga.book ?: return
+        val config = book.readConfig ?: ReadConfig()
+        config.update()
+        book.readConfig = config
+
+        execute {
+            appDb.bookDao.update(book)
+        }.onError {
+            AppLog.put("更新阅读配置失败\n${it.localizedMessage}", it)
+        }
+    }
+
     override fun onCleared() {
         super.onCleared()
         changeSourceCoroutine?.cancel()

+ 13 - 2
app/src/main/java/io/legato/kazusa/ui/book/manga/config/MangaScrollModeDialog.kt

@@ -14,6 +14,9 @@ class MangaScrollModeDialog : BaseBottomSheetDialogFragment(R.layout.dialog_mang
     private val binding by viewBinding(DialogMangaScrollModeBinding::bind)
 
     var initialAutoPageEnabled: Boolean = false
+    var initialWebtoonSidePadding: Int = 0
+    var initialScrollMode: Int = MangaScrollMode.PAGE_RIGHT_TO_LEFT
+
     var callback: Callback? = null
 
     override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
@@ -27,7 +30,7 @@ class MangaScrollModeDialog : BaseBottomSheetDialogFragment(R.layout.dialog_mang
             binding.chipGroupScrollMode.addView(Chip(requireContext()).apply {
                 text = MangaScrollMode.labelOf(mode)
                 isCheckable = true
-                isChecked = (mode == AppConfig.mangaScrollMode)
+                isChecked = (mode == initialScrollMode)
 
                 setOnClickListener {
                     callback?.onScrollModeChanged(mode)
@@ -65,9 +68,16 @@ class MangaScrollModeDialog : BaseBottomSheetDialogFragment(R.layout.dialog_mang
             }
         }
 
+        binding.checkboxVolumeKeyPage.apply {
+            isChecked = AppConfig.MangaVolumeKeyPage
+            setOnCheckedChangeListener { _, isChecked ->
+                callback?.onVolumeKeyPageChanged(isChecked)
+            }
+        }
+
         binding.scvPadding.apply {
             valueFormat = { "$it %" }
-            progress = AppConfig.webtoonSidePaddingDp
+            progress = initialWebtoonSidePadding
             onChanged = { newValue ->
                 callback?.upSidePadding(newValue)
             }
@@ -96,6 +106,7 @@ class MangaScrollModeDialog : BaseBottomSheetDialogFragment(R.layout.dialog_mang
         fun onMangaScaleDisabledChanged(disabled: Boolean)
         fun upSidePadding(padding: Int)
         fun onHideMangaTitleChanged(hide: Boolean)
+        fun onVolumeKeyPageChanged(enable: Boolean)
     }
 
 }

+ 20 - 16
app/src/main/java/io/legato/kazusa/ui/book/read/config/ReadStyleDialog.kt

@@ -2,6 +2,7 @@ package io.legato.kazusa.ui.book.read.config
 
 import android.content.DialogInterface
 import android.os.Bundle
+import android.view.Gravity
 import android.view.View
 import android.view.ViewGroup
 import androidx.core.view.get
@@ -15,6 +16,7 @@ import io.legato.kazusa.databinding.DialogReadBookStyleBinding
 import io.legato.kazusa.databinding.ItemReadStyleBinding
 import io.legato.kazusa.help.config.AppConfig
 import io.legato.kazusa.help.config.ReadBookConfig
+import io.legato.kazusa.help.config.ThemeConfig
 import io.legato.kazusa.lib.dialogs.selector
 import io.legato.kazusa.model.ReadBook
 import io.legato.kazusa.ui.book.read.ReadBookActivity
@@ -22,9 +24,8 @@ import io.legato.kazusa.ui.font.FontSelectDialog
 import io.legato.kazusa.utils.ChineseUtils
 import io.legato.kazusa.utils.postEvent
 import io.legato.kazusa.utils.showDialogFragment
+import io.legato.kazusa.utils.themeColor
 import io.legato.kazusa.utils.viewbindingdelegate.viewBinding
-import splitties.views.onLongClick
-import io.legato.kazusa.help.config.ThemeConfig
 
 class ReadStyleDialog : BaseBottomSheetDialogFragment(R.layout.dialog_read_book_style),
     FontSelectDialog.CallBack {
@@ -229,32 +230,35 @@ class ReadStyleDialog : BaseBottomSheetDialogFragment(R.layout.dialog_read_book_
             payloads: MutableList<Any>
         ) {
             binding.apply {
-                ivStyle.setText(item.name.ifBlank { "文字" })
-                ivStyle.setTextColor(item.curTextColor())
+                tvStyle.text = item.name.ifBlank { "文字" }
+                tvStyle.setTextColor(item.curTextColor())
                 ivStyle.setImageDrawable(item.curBgDrawable(100, 150))
                 if (ReadBookConfig.styleSelect == holder.layoutPosition) {
-                    //ivStyle.borderColor = accentColor
-                    ivStyle.setTextBold(true)
+                    llStyle.gravity = Gravity.TOP
+                    cdStyle.strokeColor =
+                        context.themeColor(com.google.android.material.R.attr.colorTertiary)
+                    rvStyle.setCardBackgroundColor(context.themeColor(com.google.android.material.R.attr.colorTertiary))
+                    //tvStyle.setTextBold(true)
                 } else {
-                    ivStyle.borderColor = item.curTextColor()
-                    ivStyle.setTextBold(false)
+                    cdStyle.strokeColor = item.curTextColor()
+                    //tvStyle.setTextBold(false)
                 }
             }
         }
 
         override fun registerListener(holder: ItemViewHolder, binding: ItemReadStyleBinding) {
             binding.apply {
-                ivStyle.setOnClickListener {
-                    if (ivStyle.isInView) {
-                        changeBgTextConfig(holder.layoutPosition)
-                    }
+                // ivStyle 现在是 MaterialCardView
+                cdStyle.setOnClickListener {
+                    changeBgTextConfig(holder.layoutPosition)
                 }
-                ivStyle.onLongClick(ivStyle.isInView) {
-                    if (ivStyle.isInView) {
-                        showBgTextConfig(holder.layoutPosition)
-                    }
+
+                cdStyle.setOnLongClickListener {
+                    showBgTextConfig(holder.layoutPosition)
+                    true // 表示事件已消费
                 }
             }
         }
+
     }
 }

+ 6 - 6
app/src/main/java/io/legato/kazusa/ui/book/source/manage/BookSourceAdapter.kt

@@ -1,22 +1,21 @@
 package io.legato.kazusa.ui.book.source.manage
 
+//import io.legado.app.lib.theme.backgroundColor
 import android.content.Context
-import android.graphics.Color
 import android.os.Bundle
 import android.view.View
 import android.view.ViewGroup
-import android.widget.ImageView
 import android.widget.PopupMenu
 import androidx.core.os.bundleOf
 import androidx.core.view.doOnLayout
 import androidx.recyclerview.widget.DiffUtil
 import androidx.recyclerview.widget.RecyclerView
+import com.google.android.material.card.MaterialCardView
 import io.legato.kazusa.R
 import io.legato.kazusa.base.adapter.ItemViewHolder
 import io.legato.kazusa.base.adapter.RecyclerAdapter
 import io.legato.kazusa.data.entities.BookSourcePart
 import io.legato.kazusa.databinding.ItemBookSourceBinding
-//import io.legado.app.lib.theme.backgroundColor
 import io.legato.kazusa.model.Debug
 import io.legato.kazusa.ui.login.SourceLoginActivity
 import io.legato.kazusa.ui.widget.recycler.DragSelectTouchHelper
@@ -25,6 +24,7 @@ import io.legato.kazusa.utils.buildMainHandler
 import io.legato.kazusa.utils.gone
 import io.legato.kazusa.utils.invisible
 import io.legato.kazusa.utils.startActivity
+import io.legato.kazusa.utils.themeColor
 import io.legato.kazusa.utils.visible
 import java.util.Collections
 
@@ -208,20 +208,20 @@ class BookSourceAdapter(
         popupMenu.show()
     }
 
-    private fun upShowExplore(iv: ImageView, source: BookSourcePart) {
+    private fun upShowExplore(iv: MaterialCardView, source: BookSourcePart) {
         when {
             !source.hasExploreUrl -> {
                 iv.invisible()
             }
 
             source.enabledExplore -> {
-                iv.setColorFilter(Color.GREEN)
+                iv.setCardBackgroundColor(context.themeColor(androidx.appcompat.R.attr.colorPrimary))
                 iv.visible()
                 iv.contentDescription = context.getString(R.string.tag_explore_enabled)
             }
 
             else -> {
-                iv.setColorFilter(Color.RED)
+                iv.setCardBackgroundColor(context.themeColor(com.google.android.material.R.attr.colorOnError))
                 iv.visible()
                 iv.contentDescription = context.getString(R.string.tag_explore_disabled)
             }

+ 0 - 445
app/src/main/java/io/legato/kazusa/ui/widget/image/CircleImageView.kt

@@ -1,445 +0,0 @@
-package io.legato.kazusa.ui.widget.image
-
-import android.annotation.SuppressLint
-import android.content.Context
-import android.graphics.*
-import android.graphics.drawable.BitmapDrawable
-import android.graphics.drawable.ColorDrawable
-import android.graphics.drawable.Drawable
-import android.net.Uri
-import android.text.TextPaint
-import android.util.AttributeSet
-import android.view.MotionEvent
-import android.view.View
-import android.view.ViewOutlineProvider
-import androidx.annotation.ColorInt
-import androidx.annotation.ColorRes
-import androidx.annotation.DrawableRes
-import androidx.appcompat.widget.AppCompatImageView
-import io.legato.kazusa.R
-import io.legato.kazusa.utils.getCompatColor
-import io.legato.kazusa.utils.printOnDebug
-import io.legato.kazusa.utils.spToPx
-import kotlin.math.min
-import kotlin.math.pow
-import androidx.core.graphics.createBitmap
-import io.legato.kazusa.utils.themeColor
-import androidx.core.content.withStyledAttributes
-
-@Suppress("unused", "MemberVisibilityCanBePrivate")
-class CircleImageView @JvmOverloads constructor(
-    context: Context,
-    attrs: AttributeSet? = null
-) : AppCompatImageView(context, attrs) {
-
-    private val mDrawableRect = RectF()
-    private val mBorderRect = RectF()
-
-    private val mShaderMatrix = Matrix()
-    private val mBitmapPaint = Paint()
-    private val mBorderPaint = Paint()
-    private val mCircleBackgroundPaint = Paint()
-    private val textPaint by lazy {
-        val textPaint = TextPaint()
-        textPaint.isAntiAlias = true
-        textPaint.textAlign = Paint.Align.CENTER
-        textPaint
-    }
-
-    private var mBorderColor = DEFAULT_BORDER_COLOR
-    private var mBorderWidth = DEFAULT_BORDER_WIDTH
-    private var mCircleBackgroundColor = DEFAULT_CIRCLE_BACKGROUND_COLOR
-
-    private var mBitmap: Bitmap? = null
-    private var mBitmapShader: BitmapShader? = null
-    private var mBitmapWidth: Int = 0
-    private var mBitmapHeight: Int = 0
-
-    private var mDrawableRadius: Float = 0.toFloat()
-    private var mBorderRadius: Float = 0.toFloat()
-
-    private var mColorFilter: ColorFilter? = null
-
-    private var mReady: Boolean = false
-    private var mSetupPending: Boolean = false
-    private var mBorderOverlay: Boolean = false
-    var isDisableCircularTransformation: Boolean = false
-        set(disableCircularTransformation) {
-            if (field == disableCircularTransformation) {
-                return
-            }
-            field = disableCircularTransformation
-            initializeBitmap()
-        }
-
-    var borderColor: Int
-        get() = mBorderColor
-        set(@ColorInt borderColor) {
-            if (borderColor == mBorderColor) {
-                return
-            }
-
-            mBorderColor = borderColor
-            mBorderPaint.color = mBorderColor
-            invalidate()
-        }
-
-    var circleBackgroundColor: Int
-        get() = mCircleBackgroundColor
-        set(@ColorInt circleBackgroundColor) {
-            if (circleBackgroundColor == mCircleBackgroundColor) {
-                return
-            }
-            mCircleBackgroundColor = circleBackgroundColor
-            mCircleBackgroundPaint.color = circleBackgroundColor
-            invalidate()
-        }
-
-    var borderWidth: Int
-        get() = mBorderWidth
-        set(borderWidth) {
-            if (borderWidth == mBorderWidth) {
-                return
-            }
-
-            mBorderWidth = borderWidth
-            setup()
-        }
-
-    var isBorderOverlay: Boolean
-        get() = mBorderOverlay
-        set(borderOverlay) {
-            if (borderOverlay == mBorderOverlay) {
-                return
-            }
-
-            mBorderOverlay = borderOverlay
-            setup()
-        }
-
-    private var text: String? = null
-
-    private var textColor = context.themeColor(com.google.android.material.R.attr.colorOnSurface)
-    private var textBold = false
-    var isInView = false
-
-    init {
-        context.withStyledAttributes(attrs, R.styleable.CircleImageView) {
-            mBorderWidth =
-                getDimensionPixelSize(
-                    R.styleable.CircleImageView_civ_border_width,
-                    DEFAULT_BORDER_WIDTH
-                )
-            mBorderColor =
-                getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR)
-            mBorderOverlay =
-                getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY)
-            mCircleBackgroundColor =
-                getColor(
-                    R.styleable.CircleImageView_civ_circle_background_color,
-                    DEFAULT_CIRCLE_BACKGROUND_COLOR
-                )
-            text = getString(R.styleable.CircleImageView_text)
-            contentDescription = text
-            if (hasValue(R.styleable.CircleImageView_textColor)) {
-                textColor = getColor(
-                    R.styleable.CircleImageView_textColor,
-                    context.themeColor(com.google.android.material.R.attr.colorOnSurface)
-                )
-            }
-        }
-
-        mReady = true
-
-        if (mSetupPending) {
-            setup()
-            mSetupPending = false
-        }
-    }
-
-    override fun setAdjustViewBounds(adjustViewBounds: Boolean) {
-        if (adjustViewBounds) {
-            throw IllegalArgumentException("adjustViewBounds not supported.")
-        }
-    }
-
-    override fun onDraw(canvas: Canvas) {
-        if (isDisableCircularTransformation) {
-            super.onDraw(canvas)
-            return
-        }
-        if (mBitmap == null) {
-            return
-        }
-
-        if (mCircleBackgroundColor != Color.TRANSPARENT) {
-            canvas.drawCircle(
-                mDrawableRect.centerX(),
-                mDrawableRect.centerY(),
-                mDrawableRadius,
-                mCircleBackgroundPaint
-            )
-        }
-        canvas.drawCircle(
-            mDrawableRect.centerX(),
-            mDrawableRect.centerY(),
-            mDrawableRadius,
-            mBitmapPaint
-        )
-        if (mBorderWidth > 0) {
-            canvas.drawCircle(
-                mBorderRect.centerX(),
-                mBorderRect.centerY(),
-                mBorderRadius,
-                mBorderPaint
-            )
-        }
-        drawText(canvas)
-    }
-
-    private fun drawText(canvas: Canvas) {
-        text?.let {
-            textPaint.color = textColor
-            textPaint.isFakeBoldText = textBold
-            textPaint.textSize = 15f.spToPx()
-            val fm = textPaint.fontMetrics
-            canvas.drawText(
-                it,
-                width * 0.5f,
-                (height * 0.5f + (fm.bottom - fm.top) * 0.5f - fm.bottom),
-                textPaint
-            )
-        }
-    }
-
-    fun setText(text: String?) {
-        this.text = text
-        contentDescription = text
-        invalidate()
-    }
-
-    fun setTextColor(@ColorInt textColor: Int) {
-        this.textColor = textColor
-        invalidate()
-    }
-
-    fun setTextBold(bold: Boolean) {
-        this.textBold = bold
-        invalidate()
-    }
-
-    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
-        super.onSizeChanged(w, h, oldw, oldh)
-        setup()
-    }
-
-    override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
-        super.setPadding(left, top, right, bottom)
-        setup()
-    }
-
-    override fun setPaddingRelative(start: Int, top: Int, end: Int, bottom: Int) {
-        super.setPaddingRelative(start, top, end, bottom)
-        setup()
-    }
-
-    fun setCircleBackgroundColorResource(@ColorRes circleBackgroundRes: Int) {
-        circleBackgroundColor = context.getCompatColor(circleBackgroundRes)
-    }
-
-    override fun setImageBitmap(bm: Bitmap) {
-        super.setImageBitmap(bm)
-        initializeBitmap()
-    }
-
-    override fun setImageDrawable(drawable: Drawable?) {
-        super.setImageDrawable(drawable)
-        initializeBitmap()
-    }
-
-    override fun setImageResource(@DrawableRes resId: Int) {
-        super.setImageResource(resId)
-        initializeBitmap()
-    }
-
-    override fun setImageURI(uri: Uri?) {
-        super.setImageURI(uri)
-        initializeBitmap()
-    }
-
-    override fun setColorFilter(cf: ColorFilter) {
-        if (cf === mColorFilter) {
-            return
-        }
-
-        mColorFilter = cf
-        applyColorFilter()
-        invalidate()
-    }
-
-    override fun getColorFilter(): ColorFilter? {
-        return mColorFilter
-    }
-
-    private fun applyColorFilter() {
-        mBitmapPaint.colorFilter = mColorFilter
-    }
-
-    private fun getBitmapFromDrawable(drawable: Drawable?): Bitmap? {
-        if (drawable == null) {
-            return null
-        }
-
-        if (drawable is BitmapDrawable) {
-            return drawable.bitmap
-        }
-
-        return try {
-            val bitmap: Bitmap = if (drawable is ColorDrawable) {
-                createBitmap(COLOR_DRAWABLE_DIMENSION, COLOR_DRAWABLE_DIMENSION, BITMAP_CONFIG)
-            } else {
-                createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, BITMAP_CONFIG)
-            }
-
-            val canvas = Canvas(bitmap)
-            drawable.setBounds(0, 0, canvas.width, canvas.height)
-            drawable.draw(canvas)
-            bitmap
-        } catch (e: Exception) {
-            e.printOnDebug()
-            null
-        }
-
-    }
-
-    private fun initializeBitmap() {
-        mBitmap = if (isDisableCircularTransformation) {
-            null
-        } else {
-            getBitmapFromDrawable(drawable)
-        }
-        setup()
-    }
-
-    private fun setup() {
-        if (!mReady) {
-            mSetupPending = true
-            return
-        }
-
-        if (width == 0 && height == 0) {
-            return
-        }
-
-        if (mBitmap == null) {
-            invalidate()
-            return
-        }
-
-        mBitmapShader = BitmapShader(mBitmap!!, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
-
-        mBitmapPaint.isAntiAlias = true
-        mBitmapPaint.shader = mBitmapShader
-
-        mBorderPaint.style = Paint.Style.STROKE
-        mBorderPaint.isAntiAlias = true
-        mBorderPaint.color = mBorderColor
-        mBorderPaint.strokeWidth = mBorderWidth.toFloat()
-
-        mCircleBackgroundPaint.style = Paint.Style.FILL
-        mCircleBackgroundPaint.isAntiAlias = true
-        mCircleBackgroundPaint.color = mCircleBackgroundColor
-
-        mBitmapHeight = mBitmap!!.height
-        mBitmapWidth = mBitmap!!.width
-
-        mBorderRect.set(calculateBounds())
-        mBorderRadius =
-            min(
-                (mBorderRect.height() - mBorderWidth) / 2.0f,
-                (mBorderRect.width() - mBorderWidth) / 2.0f
-            )
-
-        mDrawableRect.set(mBorderRect)
-        if (!mBorderOverlay && mBorderWidth > 0) {
-            mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f)
-        }
-        mDrawableRadius = min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f)
-
-        applyColorFilter()
-        updateShaderMatrix()
-        invalidate()
-    }
-
-    private fun calculateBounds(): RectF {
-        val availableWidth = width - paddingLeft - paddingRight
-        val availableHeight = height - paddingTop - paddingBottom
-
-        val sideLength = min(availableWidth, availableHeight)
-
-        val left = paddingLeft + (availableWidth - sideLength) / 2f
-        val top = paddingTop + (availableHeight - sideLength) / 2f
-
-        return RectF(left, top, left + sideLength, top + sideLength)
-    }
-
-    private fun updateShaderMatrix() {
-        val scale: Float
-        var dx = 0f
-        var dy = 0f
-
-        mShaderMatrix.set(null)
-
-        if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
-            scale = mDrawableRect.height() / mBitmapHeight.toFloat()
-            dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f
-        } else {
-            scale = mDrawableRect.width() / mBitmapWidth.toFloat()
-            dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f
-        }
-
-        mShaderMatrix.setScale(scale, scale)
-        mShaderMatrix.postTranslate(
-            (dx + 0.5f).toInt() + mDrawableRect.left,
-            (dy + 0.5f).toInt() + mDrawableRect.top
-        )
-
-        mBitmapShader!!.setLocalMatrix(mShaderMatrix)
-    }
-
-    @SuppressLint("ClickableViewAccessibility")
-    override fun onTouchEvent(event: MotionEvent): Boolean {
-        when (event.action) {
-            MotionEvent.ACTION_DOWN -> {
-                isInView = (inTouchableArea(event.x, event.y))
-            }
-        }
-        return super.onTouchEvent(event)
-    }
-
-    private fun inTouchableArea(x: Float, y: Float): Boolean {
-        return (x - mBorderRect.centerX()).toDouble()
-            .pow(2.0) + (y - mBorderRect.centerY()).toDouble()
-            .pow(2.0) <= mBorderRadius.toDouble().pow(2.0)
-    }
-
-    private inner class OutlineProvider : ViewOutlineProvider() {
-
-        override fun getOutline(view: View, outline: Outline) {
-            val bounds = Rect()
-            mBorderRect.roundOut(bounds)
-            outline.setRoundRect(bounds, bounds.width() / 2.0f)
-        }
-
-    }
-
-    companion object {
-        private val BITMAP_CONFIG = Bitmap.Config.ARGB_8888
-        private const val COLOR_DRAWABLE_DIMENSION = 2
-        private const val DEFAULT_BORDER_WIDTH = 0
-        private const val DEFAULT_BORDER_COLOR = Color.BLACK
-        private const val DEFAULT_CIRCLE_BACKGROUND_COLOR = Color.TRANSPARENT
-        private const val DEFAULT_BORDER_OVERLAY = false
-    }
-
-}

+ 5 - 6
app/src/main/res/layout-land/activity_book_info.xml

@@ -203,7 +203,7 @@
 
                             <com.google.android.material.button.MaterialButton
                                 android:id="@+id/btn_shelf"
-                                style="@style/Widget.Material3.Button.TonalButton"
+                                style="@style/Widget.Material3Expressive.Button.TonalButton"
                                 android:backgroundTint="?attr/colorSurfaceContainer"
                                 app:cornerRadius="16dp"
                                 android:layout_width="wrap_content"
@@ -220,7 +220,7 @@
                             <!-- 查看目录按钮 -->
                             <com.google.android.material.button.MaterialButton
                                 android:id="@+id/tv_toc_view"
-                                style="@style/Widget.Material3.Button.TonalButton"
+                                style="@style/Widget.Material3Expressive.Button.TonalButton"
                                 android:backgroundTint="?attr/colorSurfaceContainer"
                                 app:cornerRadius="16dp"
                                 android:layout_width="wrap_content"
@@ -237,7 +237,7 @@
                             <!-- 更换分组按钮 -->
                             <com.google.android.material.button.MaterialButton
                                 android:id="@+id/tv_change_group"
-                                style="@style/Widget.Material3.Button.TonalButton"
+                                style="@style/Widget.Material3Expressive.Button.TonalButton"
                                 android:backgroundTint="?attr/colorSurfaceContainer"
                                 app:cornerRadius="16dp"
                                 android:layout_width="wrap_content"
@@ -254,7 +254,7 @@
                             <!-- 更换来源按钮(保持原样) -->
                             <com.google.android.material.button.MaterialButton
                                 android:id="@+id/btn_change_source"
-                                style="@style/Widget.Material3.Button.TonalButton"
+                                style="@style/Widget.Material3Expressive.Button.TonalButton"
                                 android:backgroundTint="?attr/colorSurfaceContainer"
                                 app:cornerRadius="16dp"
                                 android:layout_width="wrap_content"
@@ -371,7 +371,6 @@
         app:iconGravity="textStart"
         app:icon="@drawable/ic_bottom_books"
         app:backgroundTint="?attr/colorSecondary"
-        app:iconTint="?attr/colorOnPrimary"
-        app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" />
+        app:iconTint="?attr/colorOnPrimary" />
 
 </androidx.coordinatorlayout.widget.CoordinatorLayout>

+ 1 - 1
app/src/main/res/layout/activity_audio_play.xml

@@ -55,7 +55,7 @@
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toBottomOf="@id/title_bar" />
 
-    <io.legato.kazusa.ui.widget.image.CircleImageView
+    <ImageView
         android:id="@+id/iv_cover"
         android:layout_width="260dp"
         android:layout_height="260dp"

+ 10 - 12
app/src/main/res/layout/activity_book_info.xml

@@ -191,14 +191,13 @@
 
                             <com.google.android.material.button.MaterialButton
                                 android:id="@+id/btn_shelf"
-                                style="@style/Widget.Material3.Button.TextButton"
+                                style="@style/Widget.Material3Expressive.Button.TextButton"
                                 android:layout_width="0dp"
                                 android:layout_height="wrap_content"
                                 android:layout_weight="1"
-                                android:layout_marginEnd="6dp"
                                 android:padding="8dp"
                                 android:text="@string/remove_from_bookshelf"
-                                android:textSize="13sp"
+                                android:textSize="12sp"
                                 app:icon="@drawable/ic_clear_all"
                                 app:iconGravity="top"
                                 app:iconPadding="4dp"
@@ -207,14 +206,14 @@
                             <!-- 查看目录按钮 -->
                             <com.google.android.material.button.MaterialButton
                                 android:id="@+id/tv_toc_view"
-                                style="@style/Widget.Material3.Button.TextButton"
+                                style="@style/Widget.Material3Expressive.Button.TextButton"
                                 android:layout_width="0dp"
                                 android:layout_height="wrap_content"
                                 android:layout_weight="1"
-                                android:layout_marginStart="8dp"
+                                android:layout_marginHorizontal="4dp"
                                 android:padding="8dp"
                                 android:text="@string/view_toc"
-                                android:textSize="13sp"
+                                android:textSize="12sp"
                                 app:icon="@drawable/ic_toc"
                                 app:iconGravity="top"
                                 app:iconPadding="4dp"
@@ -223,14 +222,14 @@
                             <!-- 更换分组按钮 -->
                             <com.google.android.material.button.MaterialButton
                                 android:id="@+id/tv_change_group"
-                                style="@style/Widget.Material3.Button.TextButton"
+                                style="@style/Widget.Material3Expressive.Button.TextButton"
                                 android:layout_width="0dp"
                                 android:layout_height="wrap_content"
+                                android:layout_marginEnd="4dp"
                                 android:layout_weight="1"
-                                android:layout_marginStart="8dp"
                                 android:padding="8dp"
                                 android:text="@string/change_group"
-                                android:textSize="13sp"
+                                android:textSize="12sp"
                                 app:icon="@drawable/ic_groups"
                                 app:iconGravity="top"
                                 app:iconPadding="4dp"
@@ -239,15 +238,14 @@
                             <!-- 更换来源按钮(保持原样) -->
                             <com.google.android.material.button.MaterialButton
                                 android:id="@+id/btn_change_source"
-                                style="@style/Widget.Material3.Button.TextButton"
+                                style="@style/Widget.Material3Expressive.Button.TextButton"
                                 android:layout_width="0dp"
                                 android:layout_height="wrap_content"
                                 android:layout_weight="1"
-                                android:layout_marginStart="8dp"
                                 android:text="@string/book_source"
                                 android:padding="8dp"
                                 app:icon="@drawable/ic_change_source"
-                                android:textSize="13sp"
+                                android:textSize="12sp"
                                 app:iconGravity="top"
                                 app:iconPadding="4dp"
                                 app:iconSize="20dp"

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

@@ -107,7 +107,7 @@
                     android:layout_width="0dp"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
-                    style="@style/Widget.Material3.Button.TonalButton"
+                    style="@style/Widget.Material3Expressive.Button.TonalButton"
                     android:padding="8dp"
                     android:text="@string/select_local_image" />
 
@@ -116,7 +116,7 @@
                     android:layout_width="0dp"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
-                    style="@style/Widget.Material3.Button.TonalButton"
+                    style="@style/Widget.Material3Expressive.Button.TonalButton"
                     android:layout_marginStart="8dp"
                     android:padding="8dp"
                     android:text="@string/change_cover_source" />
@@ -126,7 +126,7 @@
                     android:layout_width="0dp"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
-                    style="@style/Widget.Material3.Button.TonalButton"
+                    style="@style/Widget.Material3Expressive.Button.TonalButton"
                     android:layout_marginStart="8dp"
                     android:padding="8dp"
                     android:text="@string/refresh_cover" />

+ 4 - 7
app/src/main/res/layout/activity_manga.xml

@@ -50,20 +50,17 @@
             android:gravity="center"
             android:orientation="vertical">
 
-            <com.google.android.material.progressindicator.CircularProgressIndicator
+            <com.google.android.material.loadingindicator.LoadingIndicator
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                app:waveAmplitude="2dp"
-                app:waveSpeed="2dp"
-                app:wavelength="2dp"
-                android:indeterminate="true"
-                app:indicatorSize="40dp" />
+                app:indicatorSize="64dp" />
 
             <TextView
                 android:id="@+id/tv_loading_message"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="8dp"
+                android:layout_marginTop="16dp"
+                android:textStyle="bold"
                 android:text="@string/loading" />
         </LinearLayout>
 

+ 29 - 38
app/src/main/res/layout/dialog_auto_read.xml

@@ -5,60 +5,51 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:paddingHorizontal="16dp"
-    android:paddingVertical="8dp"
+    android:paddingBottom="16dp"
     android:orientation="vertical">
 
+    <com.google.android.material.bottomsheet.BottomSheetDragHandleView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal" />
+
     <LinearLayout
+        android:id="@+id/ll_tts_SpeechRate"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingVertical="8dp"
-        android:orientation="vertical">
-
-        <View
-            android:layout_width="36dp"
-            android:layout_height="4dp"
-            android:layout_gravity="center_horizontal"
-            android:background="@drawable/bg_bottom_sheet_handle"
-            android:layout_marginBottom="16dp" />
+        android:gravity="center_horizontal"
+        android:orientation="horizontal">
 
-        <LinearLayout
-            android:id="@+id/ll_tts_SpeechRate"
-            android:layout_width="match_parent"
+        <TextView
+            android:id="@+id/tv_read_speed_title"
+            style="@style/ChapterNameText"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:gravity="center_horizontal"
-            android:orientation="horizontal">
-
-            <TextView
-                android:id="@+id/tv_read_speed_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                style="@style/ChapterNameText"
-                android:text="@string/auto_page_speed" />
+            android:text="@string/auto_page_speed" />
 
-            <TextView
-                android:id="@+id/tv_read_speed"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginStart="8dp"
-                android:textSize="16sp"/>
-
-        </LinearLayout>
-
-        <com.google.android.material.slider.Slider
-            android:id="@+id/seek_auto_read"
-            android:layout_width="match_parent"
+        <TextView
+            android:id="@+id/tv_read_speed"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:valueFrom="1.0"
-            android:valueTo="60.0"
-            android:stepSize="1.0"
-            tools:ignore="UnusedAttribute" />
+            android:layout_marginStart="8dp"
+            android:textSize="16sp" />
 
     </LinearLayout>
 
+    <com.google.android.material.slider.Slider
+        android:id="@+id/seek_auto_read"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:stepSize="1.0"
+        android:valueFrom="1.0"
+        android:valueTo="60.0"
+        tools:ignore="UnusedAttribute" />
+
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginTop="8dp"
+        android:baselineAligned="false"
         android:orientation="horizontal">
 
 

+ 34 - 24
app/src/main/res/layout/dialog_book_group_edit.xml

@@ -4,24 +4,39 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:fillViewport="true"
+    android:paddingHorizontal="16dp"
+    android:paddingBottom="16dp"
     android:orientation="vertical">
 
-    <androidx.appcompat.widget.Toolbar
-        android:id="@+id/tool_bar"
+    <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:theme="?attr/actionBarStyle"
-        app:displayHomeAsUp="false"
-        app:fitStatusBar="false"
-        app:title="@string/group_edit"
-        app:titleTextAppearance="@style/ToolbarTitle" />
+        android:gravity="center"
+        android:orientation="vertical"
+        android:paddingBottom="8dp">
+
+        <com.google.android.material.bottomsheet.BottomSheetDragHandleView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal" />
+
+        <TextView
+            android:id="@+id/bottom_sheet_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/group_edit"
+            android:textSize="18sp"
+            android:textStyle="bold" />
+
+    </LinearLayout>
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         android:gravity="center_horizontal"
-        android:padding="16dp">
+        android:paddingVertical="16dp">
 
         <io.legato.kazusa.ui.widget.image.CoverImageView
             android:id="@+id/iv_cover"
@@ -60,19 +75,15 @@
                 android:layout_marginTop="8dp"
                 android:layout_marginBottom="8dp">
 
-                <io.legato.kazusa.ui.widget.text.AccentTextView
-                    android:id="@+id/tv_sort"
+                <com.google.android.material.chip.Chip
+                    android:id="@+id/chip_sort_menu"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:text="@string/sort" />
+                    android:clickable="true"
+                    android:text="排序方式"
+                    app:chipIcon="@drawable/ic_arrow_drop_down"
+                    app:chipIconVisible="true" />
 
-                <androidx.appcompat.widget.AppCompatSpinner
-                    android:id="@+id/sp_sort"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="8dp"
-                    android:entries="@array/book_sort"
-                    tools:ignore="RtlHardcoded" />
             </LinearLayout>
 
             <com.google.android.material.materialswitch.MaterialSwitch
@@ -90,14 +101,13 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
-        android:gravity="center_vertical"
-        android:paddingHorizontal="16dp">
+        android:gravity="center_vertical">
 
         <com.google.android.material.button.MaterialButton
             android:id="@+id/btn_delete"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.IconButton.Outlined"
+            style="@style/Widget.Material3Expressive.Button.IconButton.Outlined"
             android:layout_marginEnd="4dp"
             app:icon="@drawable/ic_clear_all"
             tools:ignore="RtlHardcoded" />
@@ -107,7 +117,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             app:icon="@drawable/ic_restore"
-            style="@style/Widget.Material3.Button.IconButton.Outlined"/>
+            style="@style/Widget.Material3Expressive.Button.IconButton.Outlined" />
 
         <Space
             android:layout_width="0dp"
@@ -118,7 +128,7 @@
             android:id="@+id/btn_cancel"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.TonalButton"
+            style="@style/Widget.Material3Expressive.Button.TonalButton"
             android:layout_marginEnd="8dp"
             android:text="@string/cancel" />
 
@@ -126,7 +136,7 @@
             android:id="@+id/btn_ok"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.UnelevatedButton"
+            style="@style/Widget.Material3Expressive.Button"
             android:text="@string/ok"
             tools:ignore="RtlHardcoded" />
 

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

@@ -75,7 +75,7 @@
             <!-- 删除按钮靠左 -->
             <com.google.android.material.button.MaterialButton
                 android:id="@+id/btn_delete"
-                style="@style/Widget.Material3.Button.TonalButton"
+                style="@style/Widget.Material3Expressive.Button.TonalButton"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:padding="12dp"
@@ -88,7 +88,7 @@
             <!-- 取消按钮 -->
             <com.google.android.material.button.MaterialButton
                 android:id="@+id/btn_cancel"
-                style="@style/Widget.Material3.Button.TonalButton"
+                style="@style/Widget.Material3Expressive.Button.TonalButton"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:padding="12dp"
@@ -101,7 +101,7 @@
             <!-- 确认按钮靠右 -->
             <com.google.android.material.button.MaterialButton
                 android:id="@+id/btn_ok"
-                style="@style/Widget.Material3.Button.TonalButton"
+                style="@style/Widget.Material3Expressive.Button.TonalButton"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:padding="12dp"

+ 174 - 168
app/src/main/res/layout/dialog_bookshelf_config.xml

@@ -1,225 +1,231 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.core.widget.NestedScrollView 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_height="wrap_content"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:paddingHorizontal="16dp"
     android:fillViewport="true">
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:fillViewport="true"
+        android:gravity="center"
+        android:orientation="vertical"
         android:paddingHorizontal="16dp"
-        android:paddingVertical="8dp"
-        android:orientation="vertical">
+        android:paddingBottom="8dp">
 
-        <LinearLayout
-            android:layout_width="match_parent"
+        <com.google.android.material.bottomsheet.BottomSheetDragHandleView
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:gravity="center"
-            android:paddingVertical="8dp"
-            android:paddingHorizontal="16dp">
-
-            <View
-                android:layout_width="36dp"
-                android:layout_height="4dp"
-                android:layout_gravity="center_horizontal"
-                android:background="@drawable/bg_bottom_sheet_handle"
-                android:layout_marginBottom="16dp" />
+            android:layout_gravity="center_horizontal" />
 
-            <TextView
-                android:id="@+id/bottom_sheet_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/bookshelf_layout"
-                android:textSize="18sp"
-                android:textStyle="bold" />
-
-        </LinearLayout>
-
-        <com.google.android.material.materialswitch.MaterialSwitch
-            android:id="@+id/sw_show_unread"
-            android:layout_width="match_parent"
+        <TextView
+            android:id="@+id/bottom_sheet_title"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="@string/show_unread"
-            tools:ignore="TouchTargetSizeCheck" />
+            android:text="@string/bookshelf_layout"
+            android:textSize="18sp"
+            android:textStyle="bold" />
 
-        <com.google.android.material.materialswitch.MaterialSwitch
-            android:id="@+id/sw_show_last_update_time"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/show_last_update_time"
-            tools:ignore="TouchTargetSizeCheck" />
+    </LinearLayout>
 
-        <com.google.android.material.materialswitch.MaterialSwitch
-            android:id="@+id/sw_show_wait_up_books"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/show_wait_up_count"
-            tools:ignore="TouchTargetSizeCheck" />
+    <androidx.core.widget.NestedScrollView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:fillViewport="true">
 
-        <com.google.android.material.materialswitch.MaterialSwitch
-            android:id="@+id/sw_show_bookshelf_fast_scroller"
+        <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:text="@string/show_bookshelf_fast_scroller"
-            tools:ignore="TouchTargetSizeCheck" />
+            android:orientation="vertical">
 
+            <com.google.android.material.materialswitch.MaterialSwitch
+                android:id="@+id/sw_show_unread"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/show_unread"
+                tools:ignore="TouchTargetSizeCheck" />
 
-        <TextView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingTop="8dp"
-            android:text="@string/group_style"
-            android:textSize="14sp"
-            android:textStyle="bold" />
+            <com.google.android.material.materialswitch.MaterialSwitch
+                android:id="@+id/sw_show_last_update_time"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/show_last_update_time"
+                tools:ignore="TouchTargetSizeCheck" />
 
-        <com.google.android.material.chip.ChipGroup
-            android:id="@+id/chip_group_style"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:checkableBehavior="single"
-            android:paddingBottom="8dp"
-            app:singleSelection="true"
-            app:selectionRequired="true">
-        </com.google.android.material.chip.ChipGroup>
+            <com.google.android.material.materialswitch.MaterialSwitch
+                android:id="@+id/sw_show_wait_up_books"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/show_wait_up_count"
+                tools:ignore="TouchTargetSizeCheck" />
+
+            <com.google.android.material.materialswitch.MaterialSwitch
+                android:id="@+id/sw_show_bookshelf_fast_scroller"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/show_bookshelf_fast_scroller"
+                tools:ignore="TouchTargetSizeCheck" />
 
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:paddingTop="8dp">
 
             <TextView
-                android:layout_width="wrap_content"
+                android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:text="排列视图"
+                android:paddingTop="8dp"
+                android:text="@string/group_style"
                 android:textSize="14sp"
                 android:textStyle="bold" />
 
-            <View
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:layout_weight="1"/>
-
             <com.google.android.material.chip.ChipGroup
-                android:id="@+id/chip_group_layout"
-                android:layout_width="wrap_content"
+                android:id="@+id/chip_group_style"
+                android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                app:singleSelection="true"
-                app:selectionRequired="true">
+                android:checkableBehavior="single"
+                android:paddingBottom="8dp"
+                app:selectionRequired="true"
+                app:singleSelection="true" />
 
-                <com.google.android.material.chip.Chip
-                    android:id="@+id/chip_list"
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:paddingTop="8dp">
+
+                <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:text="列表" />
-
-                <com.google.android.material.chip.Chip
-                    android:id="@+id/chip_grid"
+                    android:layout_gravity="center_vertical"
+                    android:text="@string/sortview"
+                    android:textSize="14sp"
+                    android:textStyle="bold" />
+
+                <View
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1" />
+
+                <com.google.android.material.chip.ChipGroup
+                    android:id="@+id/chip_group_layout"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:text="网格" />
-            </com.google.android.material.chip.ChipGroup>
-        </LinearLayout>
-
+                    app:selectionRequired="true"
+                    app:singleSelection="true">
+
+                    <com.google.android.material.chip.Chip
+                        android:id="@+id/chip_list"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:checkable="true"
+                        android:text="@string/list" />
+
+                    <com.google.android.material.chip.Chip
+                        android:id="@+id/chip_grid"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:checkable="true"
+                        android:text="@string/grid" />
+                </com.google.android.material.chip.ChipGroup>
+            </LinearLayout>
 
 
-        <TextView
-            android:id="@+id/slider_text"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="每行列数"
-            android:textSize="14sp"
-            android:textStyle="bold"
-            android:paddingTop="8dp" />
-
-        <com.google.android.material.slider.Slider
-            android:id="@+id/slider_grid_count"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingVertical="8dp"
-            android:valueFrom="1"
-            android:valueTo="9"
-            android:stepSize="1"
-            android:value="3" />
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal">
             <TextView
-                android:layout_width="wrap_content"
+                android:id="@+id/slider_text"
+                android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:text="@string/sort"
+                android:paddingTop="8dp"
+                android:text="@string/number_rows_columns"
                 android:textSize="14sp"
                 android:textStyle="bold" />
 
-            <View
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:layout_weight="1"/>
-
-            <com.google.android.material.chip.ChipGroup
-                android:id="@+id/chipGroupOrder"
-                android:layout_width="wrap_content"
+            <com.google.android.material.slider.Slider
+                android:id="@+id/slider_grid_count"
+                android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                app:singleSelection="true">
+                android:paddingVertical="8dp"
+                android:stepSize="1"
+                android:value="3"
+                android:valueFrom="1"
+                android:valueTo="9" />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
 
-                <com.google.android.material.chip.Chip
+                <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:id="@+id/chip_asc"
-                    android:text="升序"
-                    android:checkable="true" />
-
-                <com.google.android.material.chip.Chip
+                    android:layout_gravity="center_vertical"
+                    android:text="@string/sort"
+                    android:textSize="14sp"
+                    android:textStyle="bold" />
+
+                <View
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1" />
+
+                <com.google.android.material.chip.ChipGroup
+                    android:id="@+id/chipGroupOrder"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:id="@+id/chip_desc"
-                    android:text="降序"
-                    android:checkable="true" />
-            </com.google.android.material.chip.ChipGroup>
+                    app:singleSelection="true">
+
+                    <com.google.android.material.chip.Chip
+                        android:id="@+id/chip_asc"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:checkable="true"
+                        android:text="@string/ascending_order" />
+
+                    <com.google.android.material.chip.Chip
+                        android:id="@+id/chip_desc"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:checkable="true"
+                        android:text="@string/descending_order" />
+                </com.google.android.material.chip.ChipGroup>
+            </LinearLayout>
+
+            <com.google.android.material.chip.ChipGroup
+                android:id="@+id/chip_group_sort"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                app:chipSpacingVertical="0dp"
+                app:selectionRequired="true"
+                app:singleSelection="true" />
         </LinearLayout>
+    </androidx.core.widget.NestedScrollView>
 
-        <com.google.android.material.chip.ChipGroup
-            android:id="@+id/chip_group_sort"
-            android:layout_width="match_parent"
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingVertical="16dp">
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1" />
+
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/btnCancel"
+            style="@style/Widget.Material3Expressive.Button.OutlinedButton"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            app:singleSelection="true"
-            app:selectionRequired="true"
-            android:orientation="horizontal" />
+            android:layout_marginEnd="8dp"
+            android:text="@string/cancel" />
 
-        <LinearLayout
-            android:layout_width="match_parent"
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/btnOk"
+            style="@style/Widget.Material3Expressive.Button"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:orientation="horizontal">
-
-            <View
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:layout_weight="1"/>
-
-            <com.google.android.material.button.MaterialButton
-                android:id="@+id/btnCancel"
-                style="@style/Widget.Material3Expressive.Button.OutlinedButton"
-                android:text="取消"
-                android:layout_marginEnd="8dp"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content" />
+            android:text="@string/confirm" />
 
-            <com.google.android.material.button.MaterialButton
-                android:id="@+id/btnOk"
-                style="@style/Widget.Material3Expressive.Button"
-                android:text="确定"
-
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content" />
-
-        </LinearLayout>
     </LinearLayout>
-</androidx.core.widget.NestedScrollView>
+
+</LinearLayout>

+ 8 - 10
app/src/main/res/layout/dialog_check_source_config.xml

@@ -6,22 +6,20 @@
     android:layout_height="wrap_content"
     android:orientation="vertical"
     android:paddingHorizontal="16dp"
-    android:paddingVertical="8dp">
+    android:paddingBottom="8dp">
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical"
         android:gravity="center"
-        android:paddingVertical="8dp"
+        android:paddingBottom="8dp"
         android:paddingHorizontal="16dp">
 
-        <View
-            android:layout_width="36dp"
-            android:layout_height="4dp"
-            android:layout_gravity="center_horizontal"
-            android:background="@drawable/bg_bottom_sheet_handle"
-            android:layout_marginBottom="16dp" />
+        <com.google.android.material.bottomsheet.BottomSheetDragHandleView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal" />
 
         <TextView
             android:id="@+id/bottom_sheet_title"
@@ -98,7 +96,7 @@
             android:id="@+id/tv_cancel"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.TonalButton"
+            style="@style/Widget.Material3Expressive.Button.TonalButton"
             android:layout_marginEnd="8dp"
             android:text="@string/cancel"
             tools:ignore="RtlHardcoded" />
@@ -107,7 +105,7 @@
             android:id="@+id/tv_ok"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.TonalButton"
+            style="@style/Widget.Material3Expressive.Button"
             android:text="@string/ok"
             tools:ignore="RtlHardcoded" />
 

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

@@ -92,7 +92,7 @@
             android:id="@+id/tv_footer_left"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.TonalButton"
+            style="@style/Widget.Material3Expressive.Button.TonalButton"
             android:text="@string/btn_default_s"
             tools:ignore="RtlHardcoded" />
 
@@ -105,7 +105,7 @@
                 android:id="@+id/tv_cancel"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                style="@style/Widget.Material3.Button.TonalButton"
+                style="@style/Widget.Material3Expressive.Button.TonalButton"
                 android:layout_marginEnd="8dp"
                 android:text="@string/cancel"
                 tools:ignore="RtlHardcoded" />
@@ -114,7 +114,7 @@
                 android:id="@+id/tv_ok"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                style="@style/Widget.Material3.Button.TonalButton"
+                style="@style/Widget.Material3Expressive.Button.TonalButton"
                 android:text="@string/ok"
                 tools:ignore="RtlHardcoded" />
 

+ 7 - 12
app/src/main/res/layout/dialog_dict.xml

@@ -4,9 +4,8 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:paddingHorizontal="16dp"
-    android:paddingVertical="8dp">
+    android:paddingBottom="16dp">
 
-    <!-- 顶部标题容器 -->
     <LinearLayout
         android:id="@+id/header_layout"
         android:layout_width="0dp"
@@ -14,17 +13,15 @@
         android:orientation="vertical"
         android:gravity="center"
         android:paddingHorizontal="16dp"
-        android:paddingVertical="8dp"
+        android:paddingBottom="8dp"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent">
 
-        <View
-            android:layout_width="36dp"
-            android:layout_height="4dp"
-            android:layout_gravity="center_horizontal"
-            android:layout_marginBottom="16dp"
-            android:background="@drawable/bg_bottom_sheet_handle" />
+        <com.google.android.material.bottomsheet.BottomSheetDragHandleView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal" />
 
         <TextView
             android:id="@+id/bottom_sheet_title"
@@ -35,7 +32,6 @@
             android:textStyle="bold" />
     </LinearLayout>
 
-    <!-- TabLayout -->
     <com.google.android.material.tabs.TabLayout
         android:id="@+id/tab_layout"
         android:layout_width="match_parent"
@@ -45,7 +41,6 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/header_layout" />
 
-    <!-- LoadingIndicator 居中显示 -->
     <com.google.android.material.loadingindicator.LoadingIndicator
         android:id="@+id/rotate_loading"
         style="@style/Widget.Material3.LoadingIndicator.Contained"
@@ -57,7 +52,6 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/tab_layout" />
 
-    <!-- ScrollView 显示字典内容 -->
     <androidx.core.widget.NestedScrollView
         android:id="@+id/scroll_container"
         android:layout_width="match_parent"
@@ -72,6 +66,7 @@
             android:id="@+id/tv_dict"
             android:layout_width="match_parent"
             android:layout_height="match_parent" />
+
     </androidx.core.widget.NestedScrollView>
 
 </androidx.constraintlayout.widget.ConstraintLayout>

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

@@ -88,7 +88,7 @@
             android:id="@+id/tv_footer_left"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.TonalButton"
+            style="@style/Widget.Material3Expressive.Button.TonalButton"
             android:text="@string/test"
             tools:ignore="RtlHardcoded" />
 
@@ -101,7 +101,7 @@
                 android:id="@+id/tv_cancel"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                style="@style/Widget.Material3.Button.TonalButton"
+                style="@style/Widget.Material3Expressive.Button.TonalButton"
                 android:layout_marginEnd="8dp"
                 android:text="@string/cancel"
                 tools:ignore="RtlHardcoded" />
@@ -110,7 +110,7 @@
                 android:id="@+id/tv_ok"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                style="@style/Widget.Material3.Button.TonalButton"
+                style="@style/Widget.Material3Expressive.Button.TonalButton"
                 android:text="@string/ok"
                 tools:ignore="RtlHardcoded" />
 

+ 1 - 1
app/src/main/res/layout/dialog_file_chooser.xml

@@ -41,7 +41,7 @@
         android:id="@+id/tv_ok"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        style="@style/Widget.Material3.Button.TonalButton"
+        style="@style/Widget.Material3Expressive.Button.TonalButton"
         android:layout_margin="8dp"
         android:text="@string/ok"
         android:gravity="center" />

+ 2 - 2
app/src/main/res/layout/dialog_manga_footer_setting.xml

@@ -167,7 +167,7 @@
 
         <com.google.android.material.button.MaterialButton
             android:id="@+id/btn_color_filter"
-            style="@style/Widget.Material3.Button.TonalButton"
+            style="@style/Widget.Material3Expressive.Button.TonalButton"
             app:icon="@drawable/ic_filter"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -175,7 +175,7 @@
 
         <com.google.android.material.button.MaterialButton
             android:id="@+id/btn_click_set"
-            style="@style/Widget.Material3.Button.TonalButton"
+            style="@style/Widget.Material3Expressive.Button.TonalButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/click_regional_config"

+ 13 - 9
app/src/main/res/layout/dialog_manga_scroll_mode.xml

@@ -5,8 +5,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-
-    android:paddingVertical="8dp">
+    android:paddingBottom="16dp">
 
     <LinearLayout
         android:layout_width="match_parent"
@@ -14,14 +13,12 @@
         android:gravity="center"
         android:orientation="vertical"
         android:paddingHorizontal="16dp"
-        android:paddingVertical="8dp">
+        android:paddingBottom="8dp">
 
-        <View
-            android:layout_width="36dp"
-            android:layout_height="4dp"
-            android:layout_gravity="center_horizontal"
-            android:layout_marginBottom="16dp"
-            android:background="@drawable/bg_bottom_sheet_handle" />
+        <com.google.android.material.bottomsheet.BottomSheetDragHandleView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal" />
 
         <TextView
             android:id="@+id/bottom_sheet_title"
@@ -73,6 +70,7 @@
                 android:id="@+id/chip_autoPage"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:checkable="true"
                 android:text="@string/enable_auto_page_scroll" />
 
             <View
@@ -138,6 +136,12 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="@string/hide_manga_title" />
+
+        <com.google.android.material.checkbox.MaterialCheckBox
+            android:id="@+id/checkboxVolumeKeyPage"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/volume_key_page" />
     </LinearLayout>
 
 

+ 2 - 2
app/src/main/res/layout/dialog_open_url_confirm.xml

@@ -31,7 +31,7 @@
             android:id="@+id/btn_negative"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.TonalButton"
+            style="@style/Widget.Material3Expressive.Button.TonalButton"
             android:layout_marginEnd="8dp"
             android:text="@string/cancel" />
 
@@ -39,7 +39,7 @@
             android:id="@+id/btn_positive"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.TonalButton"
+            style="@style/Widget.Material3Expressive.Button.TonalButton"
             android:text="@string/ok" />
 
     </com.google.android.flexbox.FlexboxLayout>

+ 87 - 73
app/src/main/res/layout/dialog_read_bg_text.xml

@@ -6,19 +6,36 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
-    android:padding="16dp">
+    android:paddingHorizontal="16dp"
+    android:paddingBottom="8dp">
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="horizontal"
         android:gravity="center"
-        android:padding="6dp">
+        android:orientation="vertical"
+        android:paddingHorizontal="16dp">
+
+        <com.google.android.material.bottomsheet.BottomSheetDragHandleView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal" />
+
+    </LinearLayout>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:orientation="vertical"
+        android:paddingBottom="8dp">
 
         <TextView
             android:id="@+id/tv_name_title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
             android:text="@string/style_name"
             android:textSize="16sp"
             android:textStyle="bold"/>
@@ -27,29 +44,74 @@
             android:id="@+id/tv_name"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginStart="4dp"
-            android:layout_marginEnd="8dp"
-            android:textSize="16sp"
+            android:paddingVertical="8dp"
+            android:textSize="22sp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/tv_name_title"
             tools:text="文字" />
 
         <com.google.android.material.button.MaterialButton
             android:id="@+id/iv_edit"
-            android:layout_width="40dp"
-            android:layout_height="40dp"
-            style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
-            android:layout_marginEnd="8dp"
+            style="@style/Widget.Material3Expressive.Button.IconButton.Tonal"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
             android:contentDescription="@string/edit"
             app:iconGravity="textStart"
-            app:icon="@drawable/ic_edit" />
+            app:icon="@drawable/ic_edit"
+            app:layout_constraintBottom_toBottomOf="@id/tv_name"
+            app:layout_constraintEnd_toStartOf="@id/iv_delete"
+            app:layout_constraintTop_toTopOf="@id/tv_name" />
+
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/iv_delete"
+            style="@style/Widget.Material3Expressive.Button.IconButton.Outlined"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:contentDescription="@string/delete"
+            app:icon="@drawable/ic_clear_all"
+            app:layout_constraintBottom_toBottomOf="@id/iv_edit"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="@id/iv_edit"
+            tools:ignore="UnusedAttribute" />
 
         <com.google.android.material.button.MaterialButton
             android:id="@+id/tv_restore"
             android:layout_width="wrap_content"
-            style="@style/Widget.Material3.Button.TonalButton"
-            android:layout_height="40dp"
-            android:text="@string/restore" />
+            style="@style/Widget.Material3Expressive.Button.OutlinedButton"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="8dp"
+            android:text="@string/restore"
+            app:icon="@drawable/ic_restore"
+            app:layout_constraintEnd_toStartOf="@id/iv_import"
+            app:layout_constraintTop_toBottomOf="@id/iv_edit" />
 
-    </LinearLayout>
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/iv_import"
+            style="@style/Widget.Material3Expressive.Button.OutlinedButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="8dp"
+            android:contentDescription="@string/import_str"
+            android:text="@string/import_str"
+            app:icon="@drawable/ic_import"
+            app:layout_constraintBottom_toBottomOf="@id/tv_restore"
+            app:layout_constraintEnd_toStartOf="@id/iv_export"
+            app:layout_constraintTop_toTopOf="@id/tv_restore" />
+
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/iv_export"
+            style="@style/Widget.Material3Expressive.Button.OutlinedButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:contentDescription="@string/import_str"
+            android:text="@string/export_str"
+            app:icon="@drawable/ic_export"
+            app:layout_constraintBottom_toBottomOf="@id/iv_import"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="@id/iv_import" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
 
     <com.google.android.material.materialswitch.MaterialSwitch
         android:id="@+id/sw_dark_status_icon"
@@ -71,80 +133,31 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="center_vertical"
-        android:padding="3dp"
+        android:paddingBottom="8dp"
         android:orientation="horizontal">
 
         <com.google.android.material.button.MaterialButton
             android:id="@+id/tv_text_color"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.TonalButton"
-            android:layout_gravity="center"
-            android:gravity="center"
-            android:singleLine="true"
+            style="@style/Widget.Material3Expressive.Button.TonalButton"
+            android:layout_marginEnd="16dp"
+            android:layout_weight="1"
             app:icon="@drawable/ic_palette"
             android:text="@string/text_color"
             android:textSize="14sp"
-            tools:ignore="HardcodedText" />
+            app:cornerRadius="12dp" />
 
         <com.google.android.material.button.MaterialButton
             android:id="@+id/tv_bg_color"
-            android:layout_width="0dp"
+            style="@style/Widget.Material3Expressive.Button.TonalButton"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.TonalButton"
             android:layout_weight="1"
-            android:layout_gravity="center"
-            android:layout_marginStart="16dp"
-            android:gravity="center"
-            android:singleLine="true"
+            android:layout_width="wrap_content"
+            android:textSize="14sp"
             app:icon="@drawable/ic_fill_colors"
             android:text="@string/bg_color"
-            android:textSize="14sp"
-            tools:ignore="HardcodedText" />
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center_vertical"
-        android:orientation="horizontal">
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/iv_import"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.IconButton.Outlined"
-            android:layout_weight="1"
-            android:contentDescription="@string/import_str"
-            app:icon="@drawable/ic_import"
-            android:text="@string/import_str"
-            tools:ignore="UnusedAttribute" />
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/iv_export"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.IconButton.Outlined"
-            android:layout_weight="1"
-            android:layout_marginStart="8dp"
-            android:layout_marginEnd="8dp"
-            android:contentDescription="@string/import_str"
-            app:icon="@drawable/ic_export"
-            android:text="@string/export_str"
-            tools:ignore="UnusedAttribute" />
-
-        <com.google.android.material.button.MaterialButton
-            android:id="@+id/iv_delete"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.IconButton.Outlined"
-            android:layout_weight="1"
-            android:contentDescription="@string/delete"
-            app:icon="@drawable/ic_clear_all"
-            android:text="@string/delete"
-            tools:ignore="UnusedAttribute" />
-
+            app:cornerRadius="12dp" />
 
     </LinearLayout>
 
@@ -175,6 +188,7 @@
     <androidx.recyclerview.widget.RecyclerView
         android:id="@+id/recycler_view"
         android:layout_width="match_parent"
+        android:paddingVertical="8dp"
         android:layout_height="100dp"
         android:orientation="horizontal"
         app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"

+ 22 - 15
app/src/main/res/layout/dialog_read_book_style.xml

@@ -5,6 +5,7 @@
     xmlns:tool="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
+
     <LinearLayout
         android:id="@+id/root_view"
         android:layout_width="match_parent"
@@ -16,38 +17,43 @@
             android:layout_height="wrap_content"
             android:orientation="vertical"
             android:gravity="center"
-            android:paddingVertical="16dp"
+            android:paddingBottom="16dp"
             android:paddingHorizontal="16dp">
 
-            <View
-                android:layout_width="36dp"
-                android:layout_height="4dp"
-                android:layout_gravity="center_horizontal"
-                android:background="@drawable/bg_bottom_sheet_handle"
-                android:layout_marginBottom="16dp" />
+            <com.google.android.material.bottomsheet.BottomSheetDragHandleView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal" />
 
-            <LinearLayout
+            <androidx.constraintlayout.widget.ConstraintLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                android:gravity="center">
+                android:orientation="horizontal">
+
                 <TextView
                     android:id="@+id/bottom_sheet_title"
                     android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
+                    android:layout_height="match_parent"
+                    app:layout_constraintBottom_toBottomOf="parent"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toTopOf="parent"
                     android:text="界面设置"
                     android:textSize="18sp"
                     android:textStyle="bold" />
 
                 <com.google.android.material.button.MaterialButton
                     android:id="@+id/tv_day_night"
-                    android:layout_width="36dp"
+                    style="@style/Widget.Material3Expressive.Button.IconButton.Tonal"
                     android:layout_height="36dp"
-                    style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
+                    android:layout_width="wrap_content"
                     android:layout_marginStart="8dp"
                     app:icon="@drawable/ic_brightness"
-                    app:iconGravity="textStart" />
-            </LinearLayout>
+                    app:iconGravity="textStart"
+                    app:layout_constraintBottom_toBottomOf="parent"
+                    app:layout_constraintStart_toEndOf="@id/bottom_sheet_title"
+                    app:layout_constraintTop_toTopOf="parent" />
+            </androidx.constraintlayout.widget.ConstraintLayout>
             
         </LinearLayout>
 
@@ -311,6 +317,7 @@
             <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:paddingTop="8dp"
                 android:gravity="center_vertical"
                 android:orientation="horizontal">
 

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

@@ -46,7 +46,7 @@
             android:id="@+id/tv_footer_left"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            style="@style/Widget.Material3.Button.TonalButton"
+            style="@style/Widget.Material3Expressive.Button.TonalButton"
             android:padding="12dp"
             android:visibility="gone"
             tools:ignore="RtlHardcoded" />
@@ -64,7 +64,7 @@
                 android:id="@+id/tv_cancel"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                style="@style/Widget.Material3.Button.OutlinedButton"
+                style="@style/Widget.Material3Expressive.Button.OutlinedButton"
                 android:padding="12dp"
                 android:layout_marginEnd="8dp"
                 android:text="@string/cancel"
@@ -75,7 +75,7 @@
                 android:id="@+id/tv_ok"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                style="@style/Widget.Material3.Button.UnelevatedButton"
+                style="@style/Widget.Material3Expressive.Button"
                 android:padding="12dp"
                 android:text="@string/ok"
                 android:visibility="gone"

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

@@ -73,7 +73,7 @@
                 android:layout_height="wrap_content"
                 android:textAppearance="?attr/textAppearanceBodyMedium"
                 android:padding="8dp"
-                android:text="123"/>
+                android:text="@string/text" />
         </com.google.android.material.card.MaterialCardView>
 
         <View
@@ -94,7 +94,7 @@
                 android:layout_height="wrap_content"
                 android:textAppearance="?attr/textAppearanceBodyMedium"
                 android:padding="8dp"
-                android:text="123"/>
+                android:text="@string/text" />
         </com.google.android.material.card.MaterialCardView>
     </LinearLayout>
 
@@ -138,7 +138,7 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:padding="8dp"
-                android:text="123"
+                android:text="@string/text"
                 android:textAppearance="?attr/textAppearanceBodyMedium" />
         </com.google.android.material.card.MaterialCardView>
     </LinearLayout>

+ 1 - 1
app/src/main/res/layout/item_arrange_book.xml

@@ -66,7 +66,7 @@
         android:id="@+id/tv_group"
         android:layout_width="48dp"
         android:layout_height="40dp"
-        style="@style/Widget.Material3.Button.TonalButton"
+        style="@style/Widget.Material3Expressive.Button.TonalButton"
         android:textSize="12sp"
         android:layout_marginEnd="8dp"
         android:padding="0dp"

+ 15 - 7
app/src/main/res/layout/item_bg_image.xml

@@ -3,22 +3,30 @@
     android:layout_width="66dp"
     android:layout_height="88dp"
     xmlns:tool="http://schemas.android.com/tools"
-    android:padding="2dp"
+    android:layout_marginEnd="6dp"
     android:orientation="vertical">
 
-    <ImageView
-        android:id="@+id/iv_bg"
+    <com.google.android.material.card.MaterialCardView
         android:layout_width="match_parent"
         android:layout_height="0dp"
-        android:layout_weight="1"
-        android:scaleType="fitCenter"
-        android:contentDescription="@string/bg_image"
-        tool:src="@drawable/ic_image" />
+        android:layout_weight="1">
+
+        <ImageView
+            android:id="@+id/iv_bg"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:contentDescription="@string/bg_image"
+            android:foreground="?android:attr/selectableItemBackground"
+            android:scaleType="fitCenter"
+            tool:src="@drawable/ic_image" />
+
+    </com.google.android.material.card.MaterialCardView>
 
     <TextView
         android:id="@+id/tv_name"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:text="@string/text"
         android:singleLine="true"
         android:gravity="center" />
 

+ 1 - 1
app/src/main/res/layout/item_book_group_manage.xml

@@ -20,7 +20,7 @@
         android:layout_width="48dp"
         android:layout_height="48dp"
         android:layout_marginEnd="8dp"
-        style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
+        style="@style/Widget.Material3Expressive.Button.IconButton.Tonal"
         app:icon="@drawable/ic_edit" />
 
     <io.legato.kazusa.lib.theme.view.ThemeSwitch

+ 10 - 10
app/src/main/res/layout/item_book_source.xml

@@ -86,10 +86,11 @@
         app:layout_constraintTop_toBottomOf="@id/barrier"
         tools:ignore="RtlHardcoded" />
 
-    <io.legato.kazusa.ui.widget.image.CircleImageView
+    <com.google.android.material.card.MaterialCardView
         android:id="@+id/iv_explore"
         android:layout_width="8dp"
         android:layout_height="8dp"
+        app:strokeWidth="0dp"
         android:scaleType="centerCrop"
         android:scrollbars="none"
         android:src="@color/md_green_600"
@@ -104,25 +105,24 @@
         android:scrollbars="none"
         android:singleLine="true"
         android:visibility="gone"
+        android:layout_marginStart="4dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toLeftOf="@id/iv_progressBar"
+        app:layout_constraintStart_toEndOf="@id/iv_progressBar"
         app:layout_constraintTop_toBottomOf="@id/cb_book_source"
         tools:text="@string/debug_hint"
         tools:visibility="visible" />
 
-    <ProgressBar
+    <com.google.android.material.loadingindicator.LoadingIndicator
         android:id="@+id/iv_progressBar"
-        android:layout_width="25dp"
-        android:layout_height="25dp"
-        android:layout_gravity="start|center_vertical"
-        android:animationResolution="1000"
-        android:indeterminate="true"
-        android:indeterminateBehavior="repeat"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:layout_marginStart="4dp"
+        app:indicatorSize="24dp"
         android:scrollbars="none"
         android:visibility="gone"
         app:layout_constraintBottom_toBottomOf="@id/iv_debug_text"
-        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="@id/iv_debug_text"
         tools:visibility="visible" />
 

+ 0 - 1
app/src/main/res/layout/item_bookshelf_grid.xml

@@ -10,7 +10,6 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginBottom="4dp"
-        android:foreground="?attr/selectableItemBackground"
         android:clickable="true"
         android:focusable="true"
         app:strokeWidth="0dp"

+ 1 - 1
app/src/main/res/layout/item_bookshelf_list.xml

@@ -129,7 +129,7 @@
             android:maxLines="1"
             android:scrollbars="none"
             android:singleLine="true"
-            android:text="123"
+            android:text="@string/text"
             android:textSize="13sp"
             app:layout_constraintBottom_toBottomOf="@+id/tv_author"
             app:layout_constraintEnd_toEndOf="parent"

+ 1 - 1
app/src/main/res/layout/item_download.xml

@@ -53,7 +53,7 @@
         android:id="@+id/tv_export"
         android:layout_width="48dp"
         android:layout_height="40dp"
-        style="@style/Widget.Material3.Button.TonalButton"
+        style="@style/Widget.Material3Expressive.Button.TonalButton"
         android:textSize="12sp"
         android:padding="0dp"
         android:text="@string/export"

+ 36 - 9
app/src/main/res/layout/item_read_style.xml

@@ -1,11 +1,38 @@
 <?xml version="1.0" encoding="utf-8"?>
-<io.legato.kazusa.ui.widget.image.CircleImageView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/iv_style"
-    android:layout_width="48dp"
-    android:layout_height="48dp"
-    android:layout_marginLeft="6dp"
-    android:layout_marginRight="6dp"
-    android:scaleType="centerCrop"
-    app:civ_border_width="1dp"
-    app:text="@string/text" />
+    android:id="@+id/rv_style"
+    android:layout_width="64dp"
+    android:layout_height="72dp"
+    android:layout_marginLeft="4dp"
+    android:layout_marginRight="4dp"
+    app:cardBackgroundColor="@android:color/transparent"
+    app:strokeWidth="0dp">
+
+    <LinearLayout
+        android:id="@+id/ll_style"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center">
+
+        <com.google.android.material.card.MaterialCardView
+            android:id="@+id/cd_style"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:foreground="?android:attr/selectableItemBackground">
+
+            <ImageView
+                android:id="@+id/iv_style"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+
+            <TextView
+                android:id="@+id/tv_style"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:text="@string/text" />
+        </com.google.android.material.card.MaterialCardView>
+    </LinearLayout>
+
+</com.google.android.material.card.MaterialCardView>

+ 46 - 23
app/src/main/res/layout/item_search.xml

@@ -3,21 +3,56 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:padding="16dp"
     android:background="?attr/selectableItemBackground"
     android:orientation="horizontal"
     android:scrollbars="none">
 
     <!-- 封面图片 -->
-    <io.legato.kazusa.ui.widget.image.CoverImageView
-        android:id="@+id/iv_cover"
-        android:layout_width="80dp"
-        android:layout_height="110dp"
-        android:contentDescription="@string/img_cover"
-        android:scaleType="centerCrop"
-        android:src="@drawable/image_cover_default"
-        android:transitionName="img_cover"
-        tools:ignore="UnusedAttribute" />
+    <com.google.android.material.card.MaterialCardView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:cardCornerRadius="8dp"
+        app:strokeWidth="0dp">
+
+        <io.legato.kazusa.ui.widget.image.CoverImageView
+            android:id="@+id/iv_cover"
+            android:layout_width="80dp"
+            android:layout_height="110dp"
+            android:contentDescription="@string/img_cover"
+            android:scaleType="centerCrop"
+            android:src="@drawable/image_cover_default"
+            android:transitionName="img_cover"
+            tools:ignore="UnusedAttribute" />
+
+        <!-- 书架内标记 -->
+        <com.google.android.material.card.MaterialCardView
+            android:id="@+id/iv_in_bookshelf"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentStart="true"
+            android:layout_centerVertical="true"
+            android:layout_margin="4dp"
+            android:scaleType="centerCrop"
+            android:visibility="visible"
+            app:cardBackgroundColor="?attr/colorPrimary"
+            app:cardCornerRadius="4dp"
+            app:strokeWidth="0dp">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingHorizontal="4dp"
+                android:paddingVertical="2dp"
+                android:text="书架中"
+                android:textColor="?attr/colorSurface"
+                android:textSize="10sp"
+                tools:ignore="SmallSp" />
+        </com.google.android.material.card.MaterialCardView>
+
+    </com.google.android.material.card.MaterialCardView>
+
 
     <!-- 右侧内容区域 -->
     <LinearLayout
@@ -33,24 +68,11 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content">
 
-            <!-- 书架内标记 -->
-            <io.legato.kazusa.ui.widget.image.CircleImageView
-                android:id="@+id/iv_in_bookshelf"
-                android:layout_width="12dp"
-                android:layout_height="12dp"
-                android:layout_marginEnd="4dp"
-                android:scaleType="centerCrop"
-                android:src="@color/md_green_600"
-                android:visibility="invisible"
-                android:layout_alignParentStart="true"
-                android:layout_centerVertical="true"/>
-
             <!-- 书名 -->
             <TextView
                 android:id="@+id/tv_name"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_toEndOf="@id/iv_in_bookshelf"
                 android:layout_toStartOf="@id/bv_originCount"
                 android:singleLine="true"
                 android:text="@string/app_name"
@@ -61,8 +83,9 @@
                 android:id="@+id/bv_originCount"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
+                android:layout_alignParentEnd="true"
                 android:layout_centerVertical="true"/>
+
         </RelativeLayout>
 
         <!-- 作者 -->

+ 23 - 8
app/src/main/res/layout/view_manga_menu.xml

@@ -89,7 +89,7 @@
                 android:id="@+id/tv_pre"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
+                style="@style/Widget.Material3Expressive.Button.IconButton.Tonal"
                 app:icon="@drawable/ic_previous"
                 tools:ignore="TouchTargetSizeCheck" />
 
@@ -112,7 +112,7 @@
                 android:id="@+id/tv_next"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
+                style="@style/Widget.Material3Expressive.Button.IconButton.Tonal"
                 app:icon="@drawable/ic_next"
                 tools:ignore="TouchTargetSizeCheck" />
         </LinearLayout>
@@ -127,12 +127,19 @@
             android:paddingHorizontal="16dp"
             android:paddingVertical="8dp">
 
+            <View
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:importantForAccessibility="no" />
+
             <com.google.android.material.button.MaterialButton
                 android:id="@+id/iv_catalog"
-                style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:backgroundTint="@android:color/transparent"
+                style="@style/Widget.Material3Expressive.Button.IconButton"
+                android:background="?android:attr/selectableItemBackgroundBorderless"
+                app:iconTint="?attr/colorPrimary"
                 android:contentDescription="@string/chapter_list"
                 android:maxHeight="24dp"
                 android:tooltipText="@string/chapter_list"
@@ -148,10 +155,11 @@
 
             <com.google.android.material.button.MaterialButton
                 android:id="@+id/btn_autoPage"
-                style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:backgroundTint="@android:color/transparent"
+                style="@style/Widget.Material3Expressive.Button.IconButton"
+                android:background="?android:attr/selectableItemBackgroundBorderless"
+                app:iconTint="?attr/colorPrimary"
                 android:contentDescription="@string/auto_next_page"
                 android:tooltipText="@string/auto_next_page"
                 app:icon="@drawable/ic_auto_page"
@@ -166,10 +174,11 @@
 
             <com.google.android.material.button.MaterialButton
                 android:id="@+id/iv_setting"
-                style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:backgroundTint="@android:color/transparent"
+                style="@style/Widget.Material3Expressive.Button.IconButton"
+                android:background="?android:attr/selectableItemBackgroundBorderless"
+                app:iconTint="?attr/colorPrimary"
                 android:contentDescription="@string/setting"
                 android:maxHeight="24dp"
                 android:tooltipText="@string/setting"
@@ -177,6 +186,12 @@
                 app:iconGravity="textStart"
                 tools:ignore="NestedWeights" />
 
+            <View
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:importantForAccessibility="no" />
+
         </LinearLayout>
 
     </LinearLayout>

+ 5 - 1
app/src/main/res/values-zh/strings.xml

@@ -802,7 +802,7 @@
     <string name="auto_clear_expired">自动清除过期搜索数据</string>
     <string name="auto_clear_expired_summary">超过一天的搜索数据</string>
     <string name="re_segment">重新分段</string>
-    <string name="style_name">样式名称:</string>
+    <string name="style_name">样式名称</string>
     <string name="empty_msg_import_book">点击右上角文件夹图标,选择文件夹</string>
     <string name="scan_folder">智能扫描</string>
     <string name="import_file_name">导入文件名</string>
@@ -1230,5 +1230,9 @@
     <string name="manga_epaper_value">阈值</string>
     <string name="disable_horizontal_animation">禁用水平滚动动画</string>
     <string name="enable_manga_gray">开启图片灰色</string>
+    <string name="sortview">排列视图</string>
+    <string name="list">列表</string>
+    <string name="grid">网格</string>
+    <string name="descending_order">降序</string>
 
 </resources>

+ 6 - 0
app/src/main/res/values/strings.xml

@@ -1231,5 +1231,11 @@
     <string name="manga_epaper_value">阈值</string>
     <string name="disable_horizontal_animation">禁用水平滚动动画</string>
     <string name="enable_manga_gray">开启图片灰色</string>
+    <string name="sortview">排列视图</string>
+    <string name="list">列表</string>
+    <string name="grid">网格</string>
+    <string name="number_rows_columns">每行列数</string>
+    <string name="ascending_order">升序</string>
+    <string name="descending_order">降序</string>
 
 </resources>

+ 56 - 60
app/src/main/res/values/themes.xml

@@ -2,72 +2,12 @@
 
     //**************************************************************Theme******************************************************************************//
 
-    <!-- 透明主题 -->
-    <style name="AppTheme.Transparent" parent="Base.AppTheme">
-
-
-        <item name="colorPrimary">@color/transparent_theme_primary</item>
-        <item name="colorOnPrimary">@color/transparent_theme_onPrimary</item>
-        <item name="colorPrimaryContainer">@color/transparent_theme_primaryContainer</item>
-        <item name="colorOnPrimaryContainer">@color/transparent_theme_onPrimaryContainer</item>
-        <item name="colorSecondary">@color/transparent_theme_secondary</item>
-        <item name="colorOnSecondary">@color/transparent_theme_onSecondary</item>
-        <item name="colorSecondaryContainer">@color/transparent_theme_secondaryContainer</item>
-        <item name="colorOnSecondaryContainer">@color/transparent_theme_onSecondaryContainer</item>
-        <item name="colorTertiary">@color/transparent_theme_tertiary</item>
-        <item name="colorOnTertiary">@color/transparent_theme_onTertiary</item>
-        <item name="colorTertiaryContainer">@color/transparent_theme_tertiaryContainer</item>
-        <item name="colorOnTertiaryContainer">@color/transparent_theme_onTertiaryContainer</item>
-        <item name="colorError">@color/transparent_theme_error</item>
-        <item name="colorOnError">@color/transparent_theme_onError</item>
-        <item name="colorErrorContainer">@color/transparent_theme_errorContainer</item>
-        <item name="colorOnErrorContainer">@color/transparent_theme_onErrorContainer</item>
-        <item name="android:colorBackground">@color/transparent_theme_background</item>
-        <item name="android:textColor">@color/transparent_theme_onSurface</item>
-        <item name="colorOnBackground">@color/transparent_theme_onBackground</item>
-        <item name="colorSurface">@color/transparent_theme_surface</item>
-        <item name="colorOnSurface">@color/transparent_theme_onSurface</item>
-        <item name="colorSurfaceVariant">@color/transparent_theme_surfaceVariant</item>
-        <item name="colorOnSurfaceVariant">@color/transparent_theme_onSurfaceVariant</item>
-        <item name="colorOutline">@color/transparent_theme_outline</item>
-        <item name="colorOutlineVariant">@color/transparent_theme_outlineVariant</item>
-        <item name="colorSurfaceInverse">@color/transparent_theme_inverseSurface</item>
-        <item name="colorOnSurfaceInverse">@color/transparent_theme_inverseOnSurface</item>
-        <item name="colorPrimaryInverse">@color/transparent_theme_inversePrimary</item>
-        <item name="colorPrimaryFixed">@color/transparent_theme_primaryFixed</item>
-        <item name="colorOnPrimaryFixed">@color/transparent_theme_onPrimaryFixed</item>
-        <item name="colorPrimaryFixedDim">@color/transparent_theme_primaryFixedDim</item>
-        <item name="colorOnPrimaryFixedVariant">@color/transparent_theme_onPrimaryFixedVariant
-        </item>
-        <item name="colorSecondaryFixed">@color/transparent_theme_secondaryFixed</item>
-        <item name="colorOnSecondaryFixed">@color/transparent_theme_onSecondaryFixed</item>
-        <item name="colorSecondaryFixedDim">@color/transparent_theme_secondaryFixedDim</item>
-        <item name="colorOnSecondaryFixedVariant">@color/transparent_theme_onSecondaryFixedVariant
-        </item>
-        <item name="colorTertiaryFixed">@color/transparent_theme_tertiaryFixed</item>
-        <item name="colorOnTertiaryFixed">@color/transparent_theme_onTertiaryFixed</item>
-        <item name="colorTertiaryFixedDim">@color/transparent_theme_tertiaryFixedDim</item>
-        <item name="colorOnTertiaryFixedVariant">@color/transparent_theme_onTertiaryFixedVariant
-        </item>
-        <item name="colorSurfaceDim">@color/transparent_theme_surfaceDim</item>
-        <item name="colorSurfaceBright">@color/transparent_theme_surfaceBright</item>
-        <item name="colorSurfaceContainerLowest">@color/transparent_theme_surfaceContainerLowest
-        </item>
-        <item name="colorSurfaceContainerLow">@color/transparent_theme_surfaceContainerLow</item>
-        <item name="colorSurfaceContainer">@color/transparent_theme_surfaceContainer</item>
-        <item name="colorSurfaceContainerHigh">@color/transparent_theme_surfaceContainerHigh</item>
-        <item name="colorSurfaceContainerHighest">@color/transparent_theme_surfaceContainerHighest
-        </item>
-    </style>
-
-
     <style name="Base.AppTheme" parent="Theme.Material3Expressive.DynamicColors.DayNight.NoActionBar">
         <item name="android:windowDrawsSystemBarBackgrounds">true</item>
         <item name="android:windowLightStatusBar">true</item>
         <item name="tabStyle">@style/Widget.App.TabLayout</item>
         <item name="popupMenuBackground">@drawable/popup_background</item>
         <item name="alertDialogTheme">@style/AppTheme.AlertDialog</item>
-        <item name="chipStyle">@style/Widget.Material3.Chip.Filter</item>
     </style>
 
     <style name="Theme.Base.Dycolors" parent="Theme.Material3Expressive.DynamicColors.DayNight.NoActionBar">
@@ -374,4 +314,60 @@
         <item name="colorSurfaceContainerHighest">@color/phoebe_theme_surfaceContainerHighest</item>
     </style>
 
+    <!-- 透明主题 -->
+    <style name="AppTheme.Transparent" parent="Base.AppTheme">
+        <item name="colorPrimary">@color/transparent_theme_primary</item>
+        <item name="colorOnPrimary">@color/transparent_theme_onPrimary</item>
+        <item name="colorPrimaryContainer">@color/transparent_theme_primaryContainer</item>
+        <item name="colorOnPrimaryContainer">@color/transparent_theme_onPrimaryContainer</item>
+        <item name="colorSecondary">@color/transparent_theme_secondary</item>
+        <item name="colorOnSecondary">@color/transparent_theme_onSecondary</item>
+        <item name="colorSecondaryContainer">@color/transparent_theme_secondaryContainer</item>
+        <item name="colorOnSecondaryContainer">@color/transparent_theme_onSecondaryContainer</item>
+        <item name="colorTertiary">@color/transparent_theme_tertiary</item>
+        <item name="colorOnTertiary">@color/transparent_theme_onTertiary</item>
+        <item name="colorTertiaryContainer">@color/transparent_theme_tertiaryContainer</item>
+        <item name="colorOnTertiaryContainer">@color/transparent_theme_onTertiaryContainer</item>
+        <item name="colorError">@color/transparent_theme_error</item>
+        <item name="colorOnError">@color/transparent_theme_onError</item>
+        <item name="colorErrorContainer">@color/transparent_theme_errorContainer</item>
+        <item name="colorOnErrorContainer">@color/transparent_theme_onErrorContainer</item>
+        <item name="android:colorBackground">@color/transparent_theme_background</item>
+        <item name="android:textColor">@color/transparent_theme_onSurface</item>
+        <item name="colorOnBackground">@color/transparent_theme_onBackground</item>
+        <item name="colorSurface">@color/transparent_theme_surface</item>
+        <item name="colorOnSurface">@color/transparent_theme_onSurface</item>
+        <item name="colorSurfaceVariant">@color/transparent_theme_surfaceVariant</item>
+        <item name="colorOnSurfaceVariant">@color/transparent_theme_onSurfaceVariant</item>
+        <item name="colorOutline">@color/transparent_theme_outline</item>
+        <item name="colorOutlineVariant">@color/transparent_theme_outlineVariant</item>
+        <item name="colorSurfaceInverse">@color/transparent_theme_inverseSurface</item>
+        <item name="colorOnSurfaceInverse">@color/transparent_theme_inverseOnSurface</item>
+        <item name="colorPrimaryInverse">@color/transparent_theme_inversePrimary</item>
+        <item name="colorPrimaryFixed">@color/transparent_theme_primaryFixed</item>
+        <item name="colorOnPrimaryFixed">@color/transparent_theme_onPrimaryFixed</item>
+        <item name="colorPrimaryFixedDim">@color/transparent_theme_primaryFixedDim</item>
+        <item name="colorOnPrimaryFixedVariant">@color/transparent_theme_onPrimaryFixedVariant
+        </item>
+        <item name="colorSecondaryFixed">@color/transparent_theme_secondaryFixed</item>
+        <item name="colorOnSecondaryFixed">@color/transparent_theme_onSecondaryFixed</item>
+        <item name="colorSecondaryFixedDim">@color/transparent_theme_secondaryFixedDim</item>
+        <item name="colorOnSecondaryFixedVariant">@color/transparent_theme_onSecondaryFixedVariant
+        </item>
+        <item name="colorTertiaryFixed">@color/transparent_theme_tertiaryFixed</item>
+        <item name="colorOnTertiaryFixed">@color/transparent_theme_onTertiaryFixed</item>
+        <item name="colorTertiaryFixedDim">@color/transparent_theme_tertiaryFixedDim</item>
+        <item name="colorOnTertiaryFixedVariant">@color/transparent_theme_onTertiaryFixedVariant
+        </item>
+        <item name="colorSurfaceDim">@color/transparent_theme_surfaceDim</item>
+        <item name="colorSurfaceBright">@color/transparent_theme_surfaceBright</item>
+        <item name="colorSurfaceContainerLowest">@color/transparent_theme_surfaceContainerLowest
+        </item>
+        <item name="colorSurfaceContainerLow">@color/transparent_theme_surfaceContainerLow</item>
+        <item name="colorSurfaceContainer">@color/transparent_theme_surfaceContainer</item>
+        <item name="colorSurfaceContainerHigh">@color/transparent_theme_surfaceContainerHigh</item>
+        <item name="colorSurfaceContainerHighest">@color/transparent_theme_surfaceContainerHighest
+        </item>
+    </style>
+
 </resources>