Kaynağa Gözat

feat: 全局圆角和边框

HapeLee 3 ay önce
ebeveyn
işleme
f4982d7b7d

+ 7 - 0
app/src/main/java/io/legado/app/constant/PreferKey.kt

@@ -198,6 +198,13 @@ object PreferKey {
     const val composeEngine = "composeEngine"
     const val composeEngine = "composeEngine"
     const val useMiuixMonet = "useMiuixMonet"
     const val useMiuixMonet = "useMiuixMonet"
     const val containerOpacity = "containerOpacity"
     const val containerOpacity = "containerOpacity"
+    const val overrideBaseCardCornerRadius = "overrideBaseCardCornerRadius"
+    const val baseCardCornerRadius = "baseCardCornerRadius"
+    const val overrideBaseCardBorder = "overrideBaseCardBorder"
+    const val baseCardBorderWidth = "baseCardBorderWidth"
+    const val baseCardBorderColor = "baseCardBorderColor"
+    const val baseCardBorderColorNight = "baseCardBorderColorNight"
+    const val disableSplicedColumnGroupCornerRadius = "disableSplicedColumnGroupCornerRadius"
     const val topBarOpacity = "topBarOpacity"
     const val topBarOpacity = "topBarOpacity"
     const val bottomBarOpacity = "bottomBarOpacity"
     const val bottomBarOpacity = "bottomBarOpacity"
     const val enableBlur = "enableBlur"
     const val enableBlur = "enableBlur"

+ 42 - 20
app/src/main/java/io/legado/app/data/repository/FeatureSettingsRepositories.kt

@@ -1,45 +1,45 @@
 package io.legado.app.data.repository
 package io.legado.app.data.repository
 
 
-import io.legado.app.constant.PreferKey
+import androidx.datastore.preferences.core.Preferences
 import io.legado.app.BuildConfig
 import io.legado.app.BuildConfig
-import io.legado.app.domain.gateway.AppShellSettingsGateway
+import io.legado.app.constant.PreferKey
 import io.legado.app.domain.gateway.AppShellBooleanSetting
 import io.legado.app.domain.gateway.AppShellBooleanSetting
-import io.legado.app.domain.gateway.AppShellStringSetting
+import io.legado.app.domain.gateway.AppShellSettingsGateway
 import io.legado.app.domain.gateway.AppShellSettingsUpdate
 import io.legado.app.domain.gateway.AppShellSettingsUpdate
+import io.legado.app.domain.gateway.AppShellStringSetting
+import io.legado.app.domain.gateway.BackupSettingsGateway
+import io.legado.app.domain.gateway.BackupSettingsUpdate
+import io.legado.app.domain.gateway.CoverSettingsGateway
+import io.legado.app.domain.gateway.CoverSettingsUpdate
+import io.legado.app.domain.gateway.DownloadCacheSettingsGateway
+import io.legado.app.domain.gateway.DownloadCacheSettingsUpdate
+import io.legado.app.domain.gateway.LabSettingsGateway
+import io.legado.app.domain.gateway.LabSettingsUpdate
 import io.legado.app.domain.gateway.OtherSettingsGateway
 import io.legado.app.domain.gateway.OtherSettingsGateway
 import io.legado.app.domain.gateway.OtherSettingsUpdate
 import io.legado.app.domain.gateway.OtherSettingsUpdate
-import io.legado.app.domain.gateway.ThemeSettingsGateway
 import io.legado.app.domain.gateway.ThemeBooleanSetting
 import io.legado.app.domain.gateway.ThemeBooleanSetting
 import io.legado.app.domain.gateway.ThemeColorSlot
 import io.legado.app.domain.gateway.ThemeColorSlot
 import io.legado.app.domain.gateway.ThemeFloatSetting
 import io.legado.app.domain.gateway.ThemeFloatSetting
 import io.legado.app.domain.gateway.ThemeIntSetting
 import io.legado.app.domain.gateway.ThemeIntSetting
-import io.legado.app.domain.gateway.ThemeStringSetting
+import io.legado.app.domain.gateway.ThemeSettingsGateway
 import io.legado.app.domain.gateway.ThemeSettingsUpdate
 import io.legado.app.domain.gateway.ThemeSettingsUpdate
-import io.legado.app.domain.model.settings.AppShellSettings
-import io.legado.app.domain.gateway.DownloadCacheSettingsGateway
-import io.legado.app.domain.gateway.DownloadCacheSettingsUpdate
-import io.legado.app.domain.model.settings.DownloadCacheSettings
-import io.legado.app.domain.gateway.CoverSettingsGateway
-import io.legado.app.domain.gateway.CoverSettingsUpdate
-import io.legado.app.domain.model.settings.CoverSettings
-import io.legado.app.domain.model.settings.OtherSettings
-import io.legado.app.domain.model.settings.ThemeSettings
-import io.legado.app.domain.gateway.LabSettingsGateway
-import io.legado.app.domain.gateway.LabSettingsUpdate
+import io.legado.app.domain.gateway.ThemeStringSetting
 import io.legado.app.domain.gateway.TranslationSettingsGateway
 import io.legado.app.domain.gateway.TranslationSettingsGateway
 import io.legado.app.domain.gateway.TranslationSettingsUpdate
 import io.legado.app.domain.gateway.TranslationSettingsUpdate
 import io.legado.app.domain.model.TranslationConstants
 import io.legado.app.domain.model.TranslationConstants
+import io.legado.app.domain.model.settings.AppShellSettings
+import io.legado.app.domain.model.settings.BackupSettings
+import io.legado.app.domain.model.settings.CoverSettings
+import io.legado.app.domain.model.settings.DownloadCacheSettings
 import io.legado.app.domain.model.settings.LabSettings
 import io.legado.app.domain.model.settings.LabSettings
+import io.legado.app.domain.model.settings.OtherSettings
+import io.legado.app.domain.model.settings.ThemeSettings
 import io.legado.app.domain.model.settings.TranslationSettings
 import io.legado.app.domain.model.settings.TranslationSettings
-import io.legado.app.domain.gateway.BackupSettingsGateway
-import io.legado.app.domain.gateway.BackupSettingsUpdate
-import io.legado.app.domain.model.settings.BackupSettings
 import io.legado.app.help.config.AppConfigStore
 import io.legado.app.help.config.AppConfigStore
 import io.legado.app.help.config.compatDsBoolean
 import io.legado.app.help.config.compatDsBoolean
 import io.legado.app.help.config.compatDsFloat
 import io.legado.app.help.config.compatDsFloat
 import io.legado.app.help.config.compatDsInt
 import io.legado.app.help.config.compatDsInt
 import io.legado.app.help.config.compatDsString
 import io.legado.app.help.config.compatDsString
-import androidx.datastore.preferences.core.Preferences
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.map
@@ -142,6 +142,14 @@ class ThemeSettingsRepository : ThemeSettingsGateway {
                 ThemeBooleanSetting.UseFlexibleTopAppBar -> PreferKey.useFlexibleTopAppBar to update.value
                 ThemeBooleanSetting.UseFlexibleTopAppBar -> PreferKey.useFlexibleTopAppBar to update.value
                 ThemeBooleanSetting.BookInfoFollowCoverColor -> PreferKey.bookInfoFollowCoverColor to update.value
                 ThemeBooleanSetting.BookInfoFollowCoverColor -> PreferKey.bookInfoFollowCoverColor to update.value
                 ThemeBooleanSetting.EnableItemDivider -> PreferKey.enableItemDivider to update.value
                 ThemeBooleanSetting.EnableItemDivider -> PreferKey.enableItemDivider to update.value
+                ThemeBooleanSetting.OverrideBaseCardCornerRadius ->
+                    PreferKey.overrideBaseCardCornerRadius to update.value
+
+                ThemeBooleanSetting.OverrideBaseCardBorder ->
+                    PreferKey.overrideBaseCardBorder to update.value
+
+                ThemeBooleanSetting.DisableSplicedColumnGroupCornerRadius ->
+                    PreferKey.disableSplicedColumnGroupCornerRadius to update.value
                 ThemeBooleanSetting.EyeProtectionEnabled -> PreferKey.eyeProtectionEnabled to update.value
                 ThemeBooleanSetting.EyeProtectionEnabled -> PreferKey.eyeProtectionEnabled to update.value
                 ThemeBooleanSetting.EyeProtectionSchedule -> PreferKey.eyeProtectionSchedule to update.value
                 ThemeBooleanSetting.EyeProtectionSchedule -> PreferKey.eyeProtectionSchedule to update.value
                 ThemeBooleanSetting.ShowRefactorTip ->
                 ThemeBooleanSetting.ShowRefactorTip ->
@@ -159,12 +167,17 @@ class ThemeSettingsRepository : ThemeSettingsGateway {
                 ThemeIntSetting.BackgroundImageBlurring -> PreferKey.bgImageBlurring to update.value
                 ThemeIntSetting.BackgroundImageBlurring -> PreferKey.bgImageBlurring to update.value
                 ThemeIntSetting.BackgroundImageDarkBlurring -> PreferKey.bgImageNBlurring to update.value
                 ThemeIntSetting.BackgroundImageDarkBlurring -> PreferKey.bgImageNBlurring to update.value
                 ThemeIntSetting.ItemDividerColor -> PreferKey.itemDividerColor to update.value
                 ThemeIntSetting.ItemDividerColor -> PreferKey.itemDividerColor to update.value
+                ThemeIntSetting.BaseCardBorderColor -> PreferKey.baseCardBorderColor to update.value
+                ThemeIntSetting.BaseCardBorderColorNight ->
+                    PreferKey.baseCardBorderColorNight to update.value
                 ThemeIntSetting.ColorTemperature -> PreferKey.colorTemperature to update.value
                 ThemeIntSetting.ColorTemperature -> PreferKey.colorTemperature to update.value
             }
             }
             is ThemeSettingsUpdate.FloatValue -> when (update.setting) {
             is ThemeSettingsUpdate.FloatValue -> when (update.setting) {
                 ThemeFloatSetting.BottomBarLensRadius -> PreferKey.bottomBarLensRadius to update.value
                 ThemeFloatSetting.BottomBarLensRadius -> PreferKey.bottomBarLensRadius to update.value
                 ThemeFloatSetting.ItemDividerWidth -> PreferKey.itemDividerWidth to update.value
                 ThemeFloatSetting.ItemDividerWidth -> PreferKey.itemDividerWidth to update.value
                 ThemeFloatSetting.ItemDividerLength -> PreferKey.itemDividerLength to update.value
                 ThemeFloatSetting.ItemDividerLength -> PreferKey.itemDividerLength to update.value
+                ThemeFloatSetting.BaseCardCornerRadius -> PreferKey.baseCardCornerRadius to update.value
+                ThemeFloatSetting.BaseCardBorderWidth -> PreferKey.baseCardBorderWidth to update.value
             }
             }
             is ThemeSettingsUpdate.StringValue -> when (update.setting) {
             is ThemeSettingsUpdate.StringValue -> when (update.setting) {
                 ThemeStringSetting.BookInfoNetworkCoverBackground ->
                 ThemeStringSetting.BookInfoNetworkCoverBackground ->
@@ -420,6 +433,15 @@ private fun Preferences.toThemeSettings(): ThemeSettings = ThemeSettings(
     themeBackgroundColorNight = compatDsInt(PreferKey.themeBackgroundColorNight) ?: 0,
     themeBackgroundColorNight = compatDsInt(PreferKey.themeBackgroundColorNight) ?: 0,
     labelContainerColorNight = compatDsInt(PreferKey.labelContainerColorNight) ?: 0,
     labelContainerColorNight = compatDsInt(PreferKey.labelContainerColorNight) ?: 0,
     containerOpacity = compatDsInt(PreferKey.containerOpacity) ?: 100,
     containerOpacity = compatDsInt(PreferKey.containerOpacity) ?: 100,
+    overrideBaseCardCornerRadius =
+        compatDsBoolean(PreferKey.overrideBaseCardCornerRadius) ?: false,
+    baseCardCornerRadius = compatDsFloat(PreferKey.baseCardCornerRadius) ?: 16f,
+    overrideBaseCardBorder = compatDsBoolean(PreferKey.overrideBaseCardBorder) ?: false,
+    baseCardBorderWidth = compatDsFloat(PreferKey.baseCardBorderWidth) ?: 1f,
+    baseCardBorderColor = compatDsInt(PreferKey.baseCardBorderColor) ?: 0,
+    baseCardBorderColorNight = compatDsInt(PreferKey.baseCardBorderColorNight) ?: 0,
+    disableSplicedColumnGroupCornerRadius =
+        compatDsBoolean(PreferKey.disableSplicedColumnGroupCornerRadius) ?: false,
     topBarOpacity = compatDsInt(PreferKey.topBarOpacity) ?: 100,
     topBarOpacity = compatDsInt(PreferKey.topBarOpacity) ?: 100,
     bottomBarOpacity = compatDsInt(PreferKey.bottomBarOpacity) ?: 100,
     bottomBarOpacity = compatDsInt(PreferKey.bottomBarOpacity) ?: 100,
     enableBlur = compatDsBoolean(PreferKey.enableBlur) ?: false,
     enableBlur = compatDsBoolean(PreferKey.enableBlur) ?: false,

+ 7 - 0
app/src/main/java/io/legado/app/domain/gateway/ThemeSettingsGateway.kt

@@ -46,6 +46,9 @@ enum class ThemeBooleanSetting {
     UseFlexibleTopAppBar,
     UseFlexibleTopAppBar,
     BookInfoFollowCoverColor,
     BookInfoFollowCoverColor,
     EnableItemDivider,
     EnableItemDivider,
+    OverrideBaseCardCornerRadius,
+    OverrideBaseCardBorder,
+    DisableSplicedColumnGroupCornerRadius,
     EyeProtectionEnabled,
     EyeProtectionEnabled,
     EyeProtectionSchedule,
     EyeProtectionSchedule,
     ShowRefactorTip,
     ShowRefactorTip,
@@ -63,6 +66,8 @@ enum class ThemeIntSetting {
     BackgroundImageBlurring,
     BackgroundImageBlurring,
     BackgroundImageDarkBlurring,
     BackgroundImageDarkBlurring,
     ItemDividerColor,
     ItemDividerColor,
+    BaseCardBorderColor,
+    BaseCardBorderColorNight,
     ColorTemperature,
     ColorTemperature,
 }
 }
 
 
@@ -70,6 +75,8 @@ enum class ThemeFloatSetting {
     BottomBarLensRadius,
     BottomBarLensRadius,
     ItemDividerWidth,
     ItemDividerWidth,
     ItemDividerLength,
     ItemDividerLength,
+    BaseCardCornerRadius,
+    BaseCardBorderWidth,
 }
 }
 
 
 enum class ThemeStringSetting {
 enum class ThemeStringSetting {

+ 7 - 0
app/src/main/java/io/legado/app/domain/model/settings/ThemeSettings.kt

@@ -25,6 +25,13 @@ data class ThemeSettings(
     val themeBackgroundColorNight: Int = 0,
     val themeBackgroundColorNight: Int = 0,
     val labelContainerColorNight: Int = 0,
     val labelContainerColorNight: Int = 0,
     val containerOpacity: Int = 100,
     val containerOpacity: Int = 100,
+    val overrideBaseCardCornerRadius: Boolean = false,
+    val baseCardCornerRadius: Float = 16f,
+    val overrideBaseCardBorder: Boolean = false,
+    val baseCardBorderWidth: Float = 1f,
+    val baseCardBorderColor: Int = 0,
+    val baseCardBorderColorNight: Int = 0,
+    val disableSplicedColumnGroupCornerRadius: Boolean = false,
     val topBarOpacity: Int = 100,
     val topBarOpacity: Int = 100,
     val bottomBarOpacity: Int = 100,
     val bottomBarOpacity: Int = 100,
     val enableBlur: Boolean = false,
     val enableBlur: Boolean = false,

+ 16 - 0
app/src/main/java/io/legado/app/ui/config/themeConfig/ThemeConfig.kt

@@ -40,6 +40,22 @@ object ThemeConfig {
 
 
     var containerOpacity by prefDelegate(PreferKey.containerOpacity, 100)
     var containerOpacity by prefDelegate(PreferKey.containerOpacity, 100)
 
 
+    var overrideBaseCardCornerRadius by prefDelegate(
+        PreferKey.overrideBaseCardCornerRadius,
+        false
+    )
+    var baseCardCornerRadius by prefDelegate(PreferKey.baseCardCornerRadius, 16f)
+
+    var overrideBaseCardBorder by prefDelegate(PreferKey.overrideBaseCardBorder, false)
+    var baseCardBorderWidth by prefDelegate(PreferKey.baseCardBorderWidth, 1f)
+    var baseCardBorderColor by prefDelegate(PreferKey.baseCardBorderColor, 0)
+    var baseCardBorderColorNight by prefDelegate(PreferKey.baseCardBorderColorNight, 0)
+
+    var disableSplicedColumnGroupCornerRadius by prefDelegate(
+        PreferKey.disableSplicedColumnGroupCornerRadius,
+        false
+    )
+
     var topBarOpacity by prefDelegate(PreferKey.topBarOpacity, 100)
     var topBarOpacity by prefDelegate(PreferKey.topBarOpacity, 100)
 
 
     var bottomBarOpacity by prefDelegate(PreferKey.bottomBarOpacity, 100)
     var bottomBarOpacity by prefDelegate(PreferKey.bottomBarOpacity, 100)

+ 1 - 0
app/src/main/java/io/legado/app/ui/config/themeConfig/ThemeConfigContract.kt

@@ -22,6 +22,7 @@ sealed interface ThemeConfigSheet {
     data object MainNavigation : ThemeConfigSheet
     data object MainNavigation : ThemeConfigSheet
     data object LauncherIcon : ThemeConfigSheet
     data object LauncherIcon : ThemeConfigSheet
     data object DividerColor : ThemeConfigSheet
     data object DividerColor : ThemeConfigSheet
+    data class BaseCardBorderColor(val dark: Boolean) : ThemeConfigSheet
     data object Font : ThemeConfigSheet
     data object Font : ThemeConfigSheet
 }
 }
 
 

+ 130 - 0
app/src/main/java/io/legado/app/ui/config/themeConfig/ThemeConfigScreen.kt

@@ -790,6 +790,85 @@ fun ThemeConfigScreen(
             // Container settings
             // Container settings
             item {
             item {
                 SplicedColumnGroup(title = stringResource(R.string.theme_manage_section_container)) {
                 SplicedColumnGroup(title = stringResource(R.string.theme_manage_section_container)) {
+                    SwitchSettingItem(
+                        title = stringResource(R.string.disable_spliced_group_corner_radius),
+                        description = stringResource(R.string.disable_spliced_group_corner_radius_summary),
+                        checked = theme.disableSplicedColumnGroupCornerRadius,
+                        onCheckedChange = {
+                            updateTheme(
+                                ThemeBooleanSetting.DisableSplicedColumnGroupCornerRadius,
+                                it
+                            )
+                        }
+                    )
+                    SwitchSettingItem(
+                        title = stringResource(R.string.base_card_corner_radius_override),
+                        description = stringResource(R.string.base_card_override_summary),
+                        checked = theme.overrideBaseCardCornerRadius,
+                        onCheckedChange = {
+                            updateTheme(ThemeBooleanSetting.OverrideBaseCardCornerRadius, it)
+                        }
+                    )
+                    AnimatedVisibility(visible = theme.overrideBaseCardCornerRadius) {
+                        SliderSettingItem(
+                            title = stringResource(R.string.base_card_corner_radius),
+                            description = "${theme.baseCardCornerRadius}dp",
+                            value = theme.baseCardCornerRadius,
+                            defaultValue = 16f,
+                            valueRange = 0f..40f,
+                            steps = 79,
+                            decimal = true,
+                            onValueChange = {
+                                updateTheme(ThemeFloatSetting.BaseCardCornerRadius, it)
+                            }
+                        )
+                    }
+                    SwitchSettingItem(
+                        title = stringResource(R.string.base_card_border_override),
+                        description = stringResource(R.string.base_card_override_summary),
+                        checked = theme.overrideBaseCardBorder,
+                        onCheckedChange = {
+                            updateTheme(ThemeBooleanSetting.OverrideBaseCardBorder, it)
+                        }
+                    )
+                    AnimatedVisibility(visible = theme.overrideBaseCardBorder) {
+                        Column {
+                            SliderSettingItem(
+                                title = stringResource(R.string.border_width),
+                                description = "${theme.baseCardBorderWidth}dp",
+                                value = theme.baseCardBorderWidth,
+                                defaultValue = 1f,
+                                valueRange = 0f..5f,
+                                steps = 49,
+                                decimal = true,
+                                onValueChange = {
+                                    updateTheme(ThemeFloatSetting.BaseCardBorderWidth, it)
+                                }
+                            )
+                            BaseCardBorderColorSettingItem(
+                                title = stringResource(R.string.base_card_border_color_day),
+                                color = theme.baseCardBorderColor,
+                                onClick = {
+                                    onIntent(
+                                        ThemeConfigIntent.ShowSheet(
+                                            ThemeConfigSheet.BaseCardBorderColor(false)
+                                        )
+                                    )
+                                }
+                            )
+                            BaseCardBorderColorSettingItem(
+                                title = stringResource(R.string.base_card_border_color_night),
+                                color = theme.baseCardBorderColorNight,
+                                onClick = {
+                                    onIntent(
+                                        ThemeConfigIntent.ShowSheet(
+                                            ThemeConfigSheet.BaseCardBorderColor(true)
+                                        )
+                                    )
+                                }
+                            )
+                        }
+                    }
                     SwitchSettingItem(
                     SwitchSettingItem(
                         title = stringResource(R.string.show_divider_line),
                         title = stringResource(R.string.show_divider_line),
                         checked = theme.enableItemDivider,
                         checked = theme.enableItemDivider,
@@ -924,6 +1003,28 @@ fun ThemeConfigScreen(
         }
         }
     )
     )
 
 
+    val baseCardBorderColorSheet = state.activeSheet as? ThemeConfigSheet.BaseCardBorderColor
+    ColorPickerSheet(
+        show = baseCardBorderColorSheet != null,
+        initialColor = if (baseCardBorderColorSheet?.dark == true) {
+            theme.baseCardBorderColorNight
+        } else {
+            theme.baseCardBorderColor
+        },
+        onDismissRequest = { onIntent(ThemeConfigIntent.DismissSheet) },
+        onColorSelected = {
+            updateTheme(
+                if (baseCardBorderColorSheet?.dark == true) {
+                    ThemeIntSetting.BaseCardBorderColorNight
+                } else {
+                    ThemeIntSetting.BaseCardBorderColor
+                },
+                it
+            )
+            onIntent(ThemeConfigIntent.DismissSheet)
+        }
+    )
+
     FontSelectSheet(
     FontSelectSheet(
         show = state.activeSheet == ThemeConfigSheet.Font,
         show = state.activeSheet == ThemeConfigSheet.Font,
         title = stringResource(R.string.font_setting),
         title = stringResource(R.string.font_setting),
@@ -949,6 +1050,35 @@ fun ThemeConfigScreen(
 
 
 }
 }
 
 
+@Composable
+private fun BaseCardBorderColorSettingItem(
+    title: String,
+    color: Int,
+    onClick: () -> Unit,
+) {
+    ClickableSettingItem(
+        title = title,
+        option = if (color != 0) {
+            "#${Integer.toHexString(color).uppercase()}"
+        } else {
+            stringResource(R.string.base_card_border_color_default)
+        },
+        onClick = onClick,
+        trailingContent = {
+            Box(
+                modifier = Modifier
+                    .size(28.dp)
+                    .clip(CircleShape)
+                    .background(
+                        color.takeIf { it != 0 }?.let(::Color)
+                            ?: LegadoTheme.colorScheme.outlineVariant
+                    )
+                    .border(1.dp, MaterialTheme.colorScheme.outlineVariant, CircleShape)
+            )
+        }
+    )
+}
+
 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
 @Composable
 @Composable
 fun ThemeModeSelector(
 fun ThemeModeSelector(

+ 1 - 1
app/src/main/java/io/legado/app/ui/widget/components/GroupManageBottomSheet.kt

@@ -76,7 +76,7 @@ private fun GroupItem(
     SettingItem(
     SettingItem(
         title = group,
         title = group,
         expanded = expanded,
         expanded = expanded,
-        shape = MaterialTheme.shapes.medium,
+        cornerRadius = 12.dp,
         color = MaterialTheme.colorScheme.surface,
         color = MaterialTheme.colorScheme.surface,
         onExpandChange = { expanded = it },
         onExpandChange = { expanded = it },
         trailingContent = {
         trailingContent = {

+ 5 - 5
app/src/main/java/io/legado/app/ui/widget/components/SplicedColumnGroup.kt

@@ -14,7 +14,6 @@ import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.dp
 import io.legado.app.ui.config.themeConfig.ThemeConfig
 import io.legado.app.ui.config.themeConfig.ThemeConfig
 import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.theme.LegadoTheme
@@ -43,6 +42,7 @@ fun SplicedColumnGroup(
 ) {
 ) {
     val composeEngine = LegadoTheme.composeEngine
     val composeEngine = LegadoTheme.composeEngine
     val enableItemDivider = ThemeConfig.enableItemDivider
     val enableItemDivider = ThemeConfig.enableItemDivider
+    val cornerRadius = if (ThemeConfig.disableSplicedColumnGroupCornerRadius) 0.dp else 16.dp
     val currentIndex = remember { mutableIntStateOf(0) }
     val currentIndex = remember { mutableIntStateOf(0) }
 
 
     val groupState = remember {
     val groupState = remember {
@@ -63,12 +63,12 @@ fun SplicedColumnGroup(
 
 
         CompositionLocalProvider(LocalSplicedColumnGroupState provides groupState) {
         CompositionLocalProvider(LocalSplicedColumnGroupState provides groupState) {
             if (ThemeResolver.isMiuixEngine(composeEngine)) {
             if (ThemeResolver.isMiuixEngine(composeEngine)) {
-                MiuixCard {
+                MiuixCard(cornerRadius = cornerRadius) {
                     Column(
                     Column(
                         modifier = Modifier
                         modifier = Modifier
                             .fillMaxWidth()
                             .fillMaxWidth()
                             .animateContentSize()
                             .animateContentSize()
-                            .clip(RoundedCornerShape(16.dp))
+                            .clip(RoundedCornerShape(cornerRadius))
                     ) {
                     ) {
                         currentIndex.intValue = 0
                         currentIndex.intValue = 0
                         items()
                         items()
@@ -79,7 +79,7 @@ fun SplicedColumnGroup(
                     modifier = Modifier
                     modifier = Modifier
                         .fillMaxWidth()
                         .fillMaxWidth()
                         .animateContentSize()
                         .animateContentSize()
-                        .clip(RoundedCornerShape(16.dp)),
+                        .clip(RoundedCornerShape(cornerRadius)),
                     verticalArrangement = Arrangement.spacedBy(2.dp)
                     verticalArrangement = Arrangement.spacedBy(2.dp)
                 ) {
                 ) {
                     currentIndex.intValue = 0
                     currentIndex.intValue = 0
@@ -112,4 +112,4 @@ fun SettingItemWithDivider(
         groupState.incrementIndex()
         groupState.incrementIndex()
         content()
         content()
     }
     }
-}
+}

+ 38 - 13
app/src/main/java/io/legado/app/ui/widget/components/card/GlassCard.kt

@@ -1,6 +1,7 @@
 package io.legado.app.ui.widget.components.card
 package io.legado.app.ui.widget.components.card
 
 
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.border
 import androidx.compose.foundation.combinedClickable
 import androidx.compose.foundation.combinedClickable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Column
@@ -13,13 +14,11 @@ import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.dp
 import io.legado.app.ui.config.themeConfig.ThemeConfig
 import io.legado.app.ui.config.themeConfig.ThemeConfig
 import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.theme.ThemeResolver
 import io.legado.app.ui.theme.ThemeResolver
-import top.yukonga.miuix.kmp.theme.MiuixTheme
 import top.yukonga.miuix.kmp.utils.PressFeedbackType
 import top.yukonga.miuix.kmp.utils.PressFeedbackType
 import top.yukonga.miuix.kmp.basic.Card as MiuixCard
 import top.yukonga.miuix.kmp.basic.Card as MiuixCard
 import top.yukonga.miuix.kmp.basic.CardDefaults as MiuixCardDefaults
 import top.yukonga.miuix.kmp.basic.CardDefaults as MiuixCardDefaults
@@ -42,18 +41,44 @@ private fun BaseCard(
     val resolvedContainerColor = (containerColor ?: LegadoTheme.colorScheme.surfaceContainer)
     val resolvedContainerColor = (containerColor ?: LegadoTheme.colorScheme.surfaceContainer)
         .let { it.copy(alpha = it.alpha * alpha) }
         .let { it.copy(alpha = it.alpha * alpha) }
     val isTransparent = containerColor == Color.Transparent
     val isTransparent = containerColor == Color.Transparent
-    val shape = RoundedCornerShape(cornerRadius)
+    val resolvedCornerRadius = if (ThemeConfig.overrideBaseCardCornerRadius) {
+        ThemeConfig.baseCardCornerRadius.dp
+    } else {
+        cornerRadius
+    }
+    val resolvedBorder = if (ThemeConfig.overrideBaseCardBorder) {
+        val configuredColor = if (LegadoTheme.isDark) {
+            ThemeConfig.baseCardBorderColorNight
+        } else {
+            ThemeConfig.baseCardBorderColor
+        }
+        BorderStroke(
+            ThemeConfig.baseCardBorderWidth.dp,
+            configuredColor.takeIf { it != 0 }?.let(::Color)
+                ?: LegadoTheme.colorScheme.outlineVariant
+        )
+    } else {
+        border
+    }
+    val resolvedShape = RoundedCornerShape(resolvedCornerRadius)
+    val decoratedModifier = modifier.then(
+        if (ThemeConfig.overrideBaseCardBorder && resolvedBorder != null) {
+            Modifier.border(resolvedBorder, resolvedShape)
+        } else {
+            Modifier
+        }
+    )
 
 
     if (isTransparent) {
     if (isTransparent) {
         val clickableModifier = if (onClick != null || onLongClick != null) {
         val clickableModifier = if (onClick != null || onLongClick != null) {
-            modifier
-                .clip(shape)
+            decoratedModifier
+                .clip(resolvedShape)
                 .combinedClickable(
                 .combinedClickable(
                     onClick = { onClick?.invoke() },
                     onClick = { onClick?.invoke() },
                     onLongClick = onLongClick
                     onLongClick = onLongClick
                 )
                 )
         } else {
         } else {
-            modifier.clip(shape)
+            decoratedModifier.clip(resolvedShape)
         }
         }
         Box(
         Box(
             modifier = clickableModifier
             modifier = clickableModifier
@@ -67,8 +92,8 @@ private fun BaseCard(
         )
         )
         if (onClick != null) {
         if (onClick != null) {
             MiuixCard(
             MiuixCard(
-                modifier = modifier,
-                cornerRadius = cornerRadius,
+                modifier = decoratedModifier,
+                cornerRadius = resolvedCornerRadius,
                 pressFeedbackType = pressFeedbackType,
                 pressFeedbackType = pressFeedbackType,
                 showIndication = true,
                 showIndication = true,
                 onClick = onClick,
                 onClick = onClick,
@@ -78,8 +103,8 @@ private fun BaseCard(
             )
             )
         } else {
         } else {
             MiuixCard(
             MiuixCard(
-                modifier = modifier,
-                cornerRadius = cornerRadius,
+                modifier = decoratedModifier,
+                cornerRadius = resolvedCornerRadius,
                 content = content,
                 content = content,
                 colors = colors
                 colors = colors
             )
             )
@@ -93,7 +118,7 @@ private fun BaseCard(
         )
         )
         val clickableModifier = if (onClick != null || onLongClick != null) {
         val clickableModifier = if (onClick != null || onLongClick != null) {
             modifier
             modifier
-                .clip(RoundedCornerShape(cornerRadius))
+                .clip(resolvedShape)
                 .combinedClickable(
                 .combinedClickable(
                     onClick = { onClick?.invoke() },
                     onClick = { onClick?.invoke() },
                     onLongClick = onLongClick
                     onLongClick = onLongClick
@@ -103,12 +128,12 @@ private fun BaseCard(
         }
         }
         Surface(
         Surface(
             modifier = clickableModifier,
             modifier = clickableModifier,
-            shape = RoundedCornerShape(cornerRadius),
+            shape = resolvedShape,
             color = colors.containerColor,
             color = colors.containerColor,
             contentColor = colors.contentColor,
             contentColor = colors.contentColor,
             tonalElevation = 0.dp,
             tonalElevation = 0.dp,
             shadowElevation = elevation,
             shadowElevation = elevation,
-            border = border
+            border = resolvedBorder
         ) {
         ) {
             Column(content = content)
             Column(content = content)
         }
         }

+ 12 - 33
app/src/main/java/io/legado/app/ui/widget/components/card/SettingCard.kt

@@ -3,15 +3,13 @@ package io.legado.app.ui.widget.components.card
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.layout.ColumnScope
 import androidx.compose.foundation.layout.ColumnScope
 import androidx.compose.material.ExperimentalMaterialApi
 import androidx.compose.material.ExperimentalMaterialApi
-import androidx.compose.material3.Card
 import androidx.compose.material3.CardColors
 import androidx.compose.material3.CardColors
 import androidx.compose.material3.CardDefaults
 import androidx.compose.material3.CardDefaults
-import androidx.compose.material3.CardElevation
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Shape
-import io.legado.app.ui.config.themeConfig.ThemeConfig
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
 import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.theme.ThemeResolver
 import io.legado.app.ui.theme.ThemeResolver
 import top.yukonga.miuix.kmp.basic.BasicComponent
 import top.yukonga.miuix.kmp.basic.BasicComponent
@@ -23,15 +21,13 @@ import top.yukonga.miuix.kmp.basic.BasicComponent
 fun SettingCard(
 fun SettingCard(
     modifier: Modifier = Modifier,
     modifier: Modifier = Modifier,
     onClick: (() -> Unit)? = null,
     onClick: (() -> Unit)? = null,
-    shape: Shape = CardDefaults.shape,
+    cornerRadius: Dp = 4.dp,
     colors: CardColors? = null,
     colors: CardColors? = null,
-    elevation: CardElevation = CardDefaults.cardElevation(),
+    elevation: Dp = 0.dp,
     border: BorderStroke? = null,
     border: BorderStroke? = null,
     content: @Composable ColumnScope.() -> Unit
     content: @Composable ColumnScope.() -> Unit
 ) {
 ) {
     val composeEngine = LegadoTheme.composeEngine
     val composeEngine = LegadoTheme.composeEngine
-    val containerAlpha = ThemeConfig.containerOpacity / 100f
-
     if (ThemeResolver.isMiuixEngine(composeEngine)) {
     if (ThemeResolver.isMiuixEngine(composeEngine)) {
         BasicComponent(
         BasicComponent(
             modifier = modifier,
             modifier = modifier,
@@ -44,32 +40,15 @@ fun SettingCard(
             contentColor = MaterialTheme.colorScheme.onSecondaryContainer
             contentColor = MaterialTheme.colorScheme.onSecondaryContainer
         )
         )
 
 
-        val finalColors = CardDefaults.cardColors(
-            containerColor = baseColors.containerColor.copy(alpha = containerAlpha),
+        GlassCard(
+            modifier = modifier,
+            onClick = onClick,
+            cornerRadius = cornerRadius,
+            containerColor = baseColors.containerColor,
             contentColor = baseColors.contentColor,
             contentColor = baseColors.contentColor,
-            disabledContainerColor = baseColors.disabledContainerColor.copy(alpha = containerAlpha),
-            disabledContentColor = baseColors.disabledContentColor
+            elevation = elevation,
+            border = border,
+            content = content,
         )
         )
-
-        if (onClick != null) {
-            Card(
-                onClick = onClick,
-                modifier = modifier,
-                shape = shape,
-                colors = finalColors,
-                elevation = elevation,
-                border = border,
-                content = content
-            )
-        } else {
-            Card(
-                modifier = modifier,
-                shape = shape,
-                colors = finalColors,
-                elevation = elevation,
-                border = border,
-                content = content
-            )
-        }
     }
     }
 }
 }

+ 10 - 17
app/src/main/java/io/legado/app/ui/widget/components/settingItem/CompactSettingItems.kt

@@ -21,19 +21,12 @@ import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.semantics.Role
-import androidx.compose.ui.semantics.clearAndSetSemantics
-import androidx.compose.ui.semantics.disabled
-import androidx.compose.ui.semantics.role
-import androidx.compose.ui.semantics.semantics
-import androidx.compose.ui.semantics.stateDescription
 import androidx.compose.ui.draw.scale
 import androidx.compose.ui.draw.scale
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.graphics.vector.ImageVector
-import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.dp
-import io.legado.app.R
 import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.theme.LegadoTheme
 import io.legado.app.ui.theme.LegadoTheme.composeEngine
 import io.legado.app.ui.theme.LegadoTheme.composeEngine
 import io.legado.app.ui.theme.ThemeResolver
 import io.legado.app.ui.theme.ThemeResolver
@@ -58,7 +51,7 @@ fun CompactDropdownSettingItem(
     description: String? = null,
     description: String? = null,
     imageVector: ImageVector? = null,
     imageVector: ImageVector? = null,
     color: Color? = LegadoTheme.colorScheme.onSheetContent,
     color: Color? = LegadoTheme.colorScheme.onSheetContent,
-    shape: Shape = MaterialTheme.shapes.small,
+    cornerRadius: androidx.compose.ui.unit.Dp = 8.dp,
     onValueChange: (String) -> Unit
     onValueChange: (String) -> Unit
 ) {
 ) {
     if (ThemeResolver.isMiuixEngine(composeEngine)) {
     if (ThemeResolver.isMiuixEngine(composeEngine)) {
@@ -91,7 +84,7 @@ fun CompactDropdownSettingItem(
             description = description,
             description = description,
             imageVector = imageVector,
             imageVector = imageVector,
             color = color,
             color = color,
-            shape = shape,
+            cornerRadius = cornerRadius,
             trailingContent = {
             trailingContent = {
                 TextCard(
                 TextCard(
                     cornerRadius = 8.dp,
                     cornerRadius = 8.dp,
@@ -136,7 +129,7 @@ fun CompactSliderSettingItem(
     description: String? = null,
     description: String? = null,
     imageVector: ImageVector? = null,
     imageVector: ImageVector? = null,
     color: Color? = LegadoTheme.colorScheme.onSheetContent,
     color: Color? = LegadoTheme.colorScheme.onSheetContent,
-    shape: Shape = MaterialTheme.shapes.small,
+    cornerRadius: androidx.compose.ui.unit.Dp = 8.dp,
     onValueChange: (Float) -> Unit
     onValueChange: (Float) -> Unit
 ) {
 ) {
     var expanded by remember { mutableStateOf(false) }
     var expanded by remember { mutableStateOf(false) }
@@ -194,7 +187,7 @@ fun CompactSliderSettingItem(
             description = description,
             description = description,
             imageVector = imageVector,
             imageVector = imageVector,
             color = color,
             color = color,
-            shape = shape,
+            cornerRadius = cornerRadius,
             expanded = expanded,
             expanded = expanded,
             onExpandChange = { expanded = it },
             onExpandChange = { expanded = it },
             trailingContent = {
             trailingContent = {
@@ -243,7 +236,7 @@ fun CompactSwitchSettingItem(
     description: String? = null,
     description: String? = null,
     imageVector: ImageVector? = null,
     imageVector: ImageVector? = null,
     color: Color? = LegadoTheme.colorScheme.onSheetContent,
     color: Color? = LegadoTheme.colorScheme.onSheetContent,
-    shape: Shape = MaterialTheme.shapes.small,
+    cornerRadius: androidx.compose.ui.unit.Dp = 8.dp,
     enabled: Boolean = true,
     enabled: Boolean = true,
     onCheckedChange: (Boolean) -> Unit
     onCheckedChange: (Boolean) -> Unit
 ) {
 ) {
@@ -262,7 +255,7 @@ fun CompactSwitchSettingItem(
             description = description,
             description = description,
             imageVector = imageVector,
             imageVector = imageVector,
             color = color,
             color = color,
-            shape = shape,
+            cornerRadius = cornerRadius,
             enabled = enabled,
             enabled = enabled,
             semanticRole = Role.Switch,
             semanticRole = Role.Switch,
             semanticToggleState = checked,
             semanticToggleState = checked,
@@ -287,7 +280,7 @@ fun CompactClickableSettingItem(
     description: String? = null,
     description: String? = null,
     imageVector: ImageVector? = null,
     imageVector: ImageVector? = null,
     color: Color? = LegadoTheme.colorScheme.onSheetContent,
     color: Color? = LegadoTheme.colorScheme.onSheetContent,
-    shape: Shape = MaterialTheme.shapes.small,
+    cornerRadius: androidx.compose.ui.unit.Dp = 8.dp,
     trailingContent: (@Composable () -> Unit)? = null,
     trailingContent: (@Composable () -> Unit)? = null,
     onClick: () -> Unit
     onClick: () -> Unit
 ) {
 ) {
@@ -304,7 +297,7 @@ fun CompactClickableSettingItem(
             description = description,
             description = description,
             imageVector = imageVector,
             imageVector = imageVector,
             color = color,
             color = color,
-            shape = shape,
+            cornerRadius = cornerRadius,
             trailingContent = trailingContent ?: {
             trailingContent = trailingContent ?: {
                 Icon(
                 Icon(
                     imageVector = Icons.Default.ChevronRight,
                     imageVector = Icons.Default.ChevronRight,

+ 8 - 10
app/src/main/java/io/legado/app/ui/widget/components/settingItem/SettingItem.kt

@@ -28,7 +28,6 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.rotate
 import androidx.compose.ui.draw.rotate
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.painter.Painter
 import androidx.compose.ui.graphics.painter.Painter
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.semantics.Role
@@ -51,7 +50,7 @@ fun SettingItem(
     painter: Painter? = null,
     painter: Painter? = null,
     imageVector: ImageVector? = null,
     imageVector: ImageVector? = null,
     color: Color? = null,
     color: Color? = null,
-    shape: Shape = MaterialTheme.shapes.extraSmall,
+    cornerRadius: androidx.compose.ui.unit.Dp = 4.dp,
     title: String,
     title: String,
     description: String? = null,
     description: String? = null,
     option: String? = null,
     option: String? = null,
@@ -74,7 +73,7 @@ fun SettingItem(
     SettingCard(
     SettingCard(
         modifier = modifier
         modifier = modifier
             .fillMaxWidth(),
             .fillMaxWidth(),
-        shape = shape,
+        cornerRadius = cornerRadius,
         colors = CardDefaults.cardColors(
         colors = CardDefaults.cardColors(
             containerColor = color ?: MaterialTheme.colorScheme.surfaceContainerLow
             containerColor = color ?: MaterialTheme.colorScheme.surfaceContainerLow
         ),
         ),
@@ -122,12 +121,6 @@ fun SettingItem(
                         }
                         }
                     }
                     }
                 } else null,
                 } else null,
-                headlineContent = {
-                    AppText(
-                        text = title,
-                        style = LegadoTheme.typography.titleMedium
-                    )
-                },
                 supportingContent = if (description != null || option != null) {
                 supportingContent = if (description != null || option != null) {
                     {
                     {
                         Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
                         Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
@@ -174,7 +167,12 @@ fun SettingItem(
                     }
                     }
                 },
                 },
                 colors = ListItemDefaults.colors(containerColor = Color.Transparent),
                 colors = ListItemDefaults.colors(containerColor = Color.Transparent),
-            )
+            ) {
+                AppText(
+                    text = title,
+                    style = LegadoTheme.typography.titleMedium
+                )
+            }
 
 
             if (isExpandable) {
             if (isExpandable) {
                 AnimatedVisibility(
                 AnimatedVisibility(

+ 9 - 0
app/src/main/res/values-zh-rCN/strings.xml

@@ -1820,6 +1820,15 @@
     <string name="nav_bar_color">导航栏颜色</string>
     <string name="nav_bar_color">导航栏颜色</string>
     <string name="border_setting">边框设置</string>
     <string name="border_setting">边框设置</string>
     <string name="show_container_border">显示容器边框</string>
     <string name="show_container_border">显示容器边框</string>
+    <string name="base_card_corner_radius_override">覆盖卡片圆角</string>
+    <string name="base_card_corner_radius">卡片圆角</string>
+    <string name="base_card_border_override">覆盖卡片边框</string>
+    <string name="base_card_border_color_day">日间卡片边框颜色</string>
+    <string name="base_card_border_color_night">夜间卡片边框颜色</string>
+    <string name="base_card_border_color_default">主题默认颜色</string>
+    <string name="base_card_override_summary">关闭时保留各卡片的默认值</string>
+    <string name="disable_spliced_group_corner_radius">关闭设置分组圆角</string>
+    <string name="disable_spliced_group_corner_radius_summary">让 SplicedColumnGroup 使用直角外轮廓</string>
     <string name="border_width">边框粗细</string>
     <string name="border_width">边框粗细</string>
     <string name="border_style">边框样式</string>
     <string name="border_style">边框样式</string>
     <string name="solid_border">实线</string>
     <string name="solid_border">实线</string>

+ 9 - 0
app/src/main/res/values-zh-rHK/strings.xml

@@ -1321,6 +1321,15 @@
     <string name="nav_bar_color">导航栏颜色</string>
     <string name="nav_bar_color">导航栏颜色</string>
     <string name="border_setting">边框设置</string>
     <string name="border_setting">边框设置</string>
     <string name="show_container_border">显示容器边框</string>
     <string name="show_container_border">显示容器边框</string>
+    <string name="base_card_corner_radius_override">覆寫卡片圓角</string>
+    <string name="base_card_corner_radius">卡片圓角</string>
+    <string name="base_card_border_override">覆寫卡片邊框</string>
+    <string name="base_card_border_color_day">日間卡片邊框顏色</string>
+    <string name="base_card_border_color_night">夜間卡片邊框顏色</string>
+    <string name="base_card_border_color_default">主題預設顏色</string>
+    <string name="base_card_override_summary">關閉時保留各卡片的預設值</string>
+    <string name="disable_spliced_group_corner_radius">關閉設定群組圓角</string>
+    <string name="disable_spliced_group_corner_radius_summary">讓 SplicedColumnGroup 使用直角外框</string>
     <string name="border_width">边框粗细</string>
     <string name="border_width">边框粗细</string>
     <string name="border_style">边框样式</string>
     <string name="border_style">边框样式</string>
     <string name="solid_border">实线</string>
     <string name="solid_border">实线</string>

+ 9 - 0
app/src/main/res/values-zh-rTW/strings.xml

@@ -1325,6 +1325,15 @@
     <string name="nav_bar_color">导航栏颜色</string>
     <string name="nav_bar_color">导航栏颜色</string>
     <string name="border_setting">边框设置</string>
     <string name="border_setting">边框设置</string>
     <string name="show_container_border">显示容器边框</string>
     <string name="show_container_border">显示容器边框</string>
+    <string name="base_card_corner_radius_override">覆寫卡片圓角</string>
+    <string name="base_card_corner_radius">卡片圓角</string>
+    <string name="base_card_border_override">覆寫卡片邊框</string>
+    <string name="base_card_border_color_day">日間卡片邊框顏色</string>
+    <string name="base_card_border_color_night">夜間卡片邊框顏色</string>
+    <string name="base_card_border_color_default">主題預設顏色</string>
+    <string name="base_card_override_summary">關閉時保留各卡片的預設值</string>
+    <string name="disable_spliced_group_corner_radius">關閉設定群組圓角</string>
+    <string name="disable_spliced_group_corner_radius_summary">讓 SplicedColumnGroup 使用直角外框</string>
     <string name="border_width">边框粗细</string>
     <string name="border_width">边框粗细</string>
     <string name="border_style">边框样式</string>
     <string name="border_style">边框样式</string>
     <string name="solid_border">实线</string>
     <string name="solid_border">实线</string>

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

@@ -109,6 +109,15 @@
     <string name="background_color">Background Color</string>
     <string name="background_color">Background Color</string>
     <string name="border_setting">Border Settings</string>
     <string name="border_setting">Border Settings</string>
     <string name="show_container_border">Show Container Border</string>
     <string name="show_container_border">Show Container Border</string>
+    <string name="base_card_corner_radius_override">Override card corner radius</string>
+    <string name="base_card_corner_radius">Card corner radius</string>
+    <string name="base_card_border_override">Override card border</string>
+    <string name="base_card_border_color_day">Day card border color</string>
+    <string name="base_card_border_color_night">Night card border color</string>
+    <string name="base_card_border_color_default">Theme default</string>
+    <string name="base_card_override_summary">When disabled, each card keeps its default value</string>
+    <string name="disable_spliced_group_corner_radius">Disable setting group corner radius</string>
+    <string name="disable_spliced_group_corner_radius_summary">Use square outer corners for SplicedColumnGroup</string>
     <string name="border_width">Border Width</string>
     <string name="border_width">Border Width</string>
     <string name="border_style">Border Style</string>
     <string name="border_style">Border Style</string>
     <string name="solid_border">Solid</string>
     <string name="solid_border">Solid</string>