[优化] 添加未开启模糊时的顶栏与底栏透明度选项

This commit is contained in:
HapeLee
2026-03-28 01:01:57 +08:00
parent f612b7958e
commit f31138338b
11 changed files with 144 additions and 71 deletions
@@ -186,6 +186,8 @@ object PreferKey {
const val materialVersion = "materialVersion"
const val composeEngine = "composeEngine"
const val containerOpacity = "containerOpacity"
const val topBarOpacity = "topBarOpacity"
const val bottomBarOpacity = "bottomBarOpacity"
const val enableBlur = "enableBlur"
const val enableProgressiveBlur = "enableProgressiveBlur"
const val useFlexibleTopAppBar = "useFlexibleTopAppBar"
@@ -9,6 +9,10 @@ object ThemeConfig {
var containerOpacity by prefDelegate(PreferKey.containerOpacity, 100)
var topBarOpacity by prefDelegate(PreferKey.topBarOpacity, 100)
var bottomBarOpacity by prefDelegate(PreferKey.bottomBarOpacity, 100)
var enableBlur by prefDelegate(PreferKey.enableBlur, false)
var enableProgressiveBlur by prefDelegate(PreferKey.enableProgressiveBlur, true)
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.Context
import android.os.Handler
import android.os.Looper
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Canvas
@@ -365,6 +366,51 @@ fun ThemeConfigScreen(
checked = ThemeConfig.useFlexibleTopAppBar,
onCheckedChange = { ThemeConfig.useFlexibleTopAppBar = it }
)
SwitchSettingItem(
title = stringResource(R.string.is_blur_enable),
checked = ThemeConfig.enableBlur,
onCheckedChange = {
ThemeConfig.enableBlur = it
if (!it) ThemeConfig.enableProgressiveBlur = false
}
)
AnimatedVisibility(visible = ThemeConfig.enableBlur) {
SwitchSettingItem(
title = stringResource(R.string.is_blur_progressive_enable),
checked = ThemeConfig.enableProgressiveBlur,
onCheckedChange = { ThemeConfig.enableProgressiveBlur = it }
)
}
AnimatedVisibility(visible = !ThemeConfig.enableBlur) {
Column(
verticalArrangement = Arrangement.spacedBy(2.dp)
) {
SliderSettingItem(
title = stringResource(R.string.top_bar_opacity),
description = stringResource(
R.string.top_bar_opacity_summary,
ThemeConfig.topBarOpacity
),
value = ThemeConfig.topBarOpacity.toFloat(),
defaultValue = 100f,
valueRange = 0f..100f,
steps = 99,
onValueChange = { ThemeConfig.topBarOpacity = it.toInt() }
)
SliderSettingItem(
title = stringResource(R.string.bottom_bar_opacity),
description = stringResource(
R.string.bottom_bar_opacity_summary,
ThemeConfig.bottomBarOpacity
),
value = ThemeConfig.bottomBarOpacity.toFloat(),
defaultValue = 100f,
valueRange = 0f..100f,
steps = 99,
onValueChange = { ThemeConfig.bottomBarOpacity = it.toInt() }
)
}
}
SliderSettingItem(
title = stringResource(R.string.container_opacity),
description = stringResource(
@@ -377,18 +423,6 @@ fun ThemeConfigScreen(
steps = 99,
onValueChange = { ThemeConfig.containerOpacity = it.toInt() }
)
SwitchSettingItem(
title = stringResource(R.string.is_blur_enable),
checked = ThemeConfig.enableBlur,
onCheckedChange = { ThemeConfig.enableBlur = it }
)
if (ThemeConfig.enableBlur) {
SwitchSettingItem(
title = stringResource(R.string.is_blur_progressive_enable),
checked = ThemeConfig.enableProgressiveBlur,
onCheckedChange = { ThemeConfig.enableProgressiveBlur = it }
)
}
}
SplicedColumnGroup(title = stringResource(R.string.day)) {
@@ -56,6 +56,7 @@ import io.legado.app.R
import io.legado.app.ui.book.info.BookInfoActivity
import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.config.mainConfig.MainConfig
import io.legado.app.ui.config.themeConfig.ThemeConfig
import io.legado.app.ui.main.bookshelf.BookshelfScreen
import io.legado.app.ui.main.bookshelf.BookshelfViewModel
import io.legado.app.ui.main.explore.ExploreScreen
@@ -243,7 +244,10 @@ fun MainScreen(
containerColor = GlassDefaults.glassColor(
noBlurColor = BottomAppBarDefaults.containerColor,
blurAlpha = GlassDefaults.DefaultBlurAlpha
)
).let { baseColor ->
val opacity = (ThemeConfig.bottomBarOpacity.coerceIn(0, 100)) / 100f
baseColor.copy(alpha = (baseColor.alpha * opacity).coerceIn(0f, 1f))
}
) {
val alwaysShowLabel = when (labelVisibilityMode) {
"labeled" -> true
@@ -1,6 +1,7 @@
package io.legado.app.ui.main.bookshelf
import android.content.res.Configuration
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -95,7 +96,9 @@ fun BookshelfConfigSheet(
// Layout Mode
val layoutMode =
if (isLandscape) BookshelfConfig.bookshelfLayoutModeLandscape else BookshelfConfig.bookshelfLayoutModePortrait
if (isLandscape) BookshelfConfig.bookshelfLayoutModeLandscape
else BookshelfConfig.bookshelfLayoutModePortrait
CompactDropdownSettingItem(
title = "布局模式",
description = stringResource(if (isLandscape) R.string.screen_landscape else R.string.screen_portrait),
@@ -109,59 +112,61 @@ fun BookshelfConfigSheet(
}
)
if (layoutMode == 1) {
CompactDropdownSettingItem(
title = "网格样式",
selectedValue = BookshelfConfig.bookshelfGridLayout.toString(),
displayEntries = stringArrayResource(R.array.bookshelf_grid_layout),
entryValues = Array(stringArrayResource(R.array.bookshelf_grid_layout).size) { it.toString() },
imageVector = Icons.Default.ViewCompact,
onValueChange = { BookshelfConfig.bookshelfGridLayout = it.toInt() }
)
CompactSwitchSettingItem(
title = "标题小字体",
checked = BookshelfConfig.bookshelfTitleSmallFont,
imageVector = Icons.Default.TextFormat,
color = MaterialTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfTitleSmallFont = it }
)
AnimatedVisibility(
visible = layoutMode == 1
) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
CompactDropdownSettingItem(
title = "网格样式",
selectedValue = BookshelfConfig.bookshelfGridLayout.toString(),
displayEntries = stringArrayResource(R.array.bookshelf_grid_layout),
entryValues = Array(stringArrayResource(R.array.bookshelf_grid_layout).size) { it.toString() },
imageVector = Icons.Default.ViewCompact,
onValueChange = { BookshelfConfig.bookshelfGridLayout = it.toInt() }
)
CompactSwitchSettingItem(
title = "标题居中",
checked = BookshelfConfig.bookshelfTitleCenter,
color = MaterialTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfTitleCenter = it }
)
} else {
CompactSwitchSettingItem(
title = "紧凑模式",
checked = BookshelfConfig.bookshelfLayoutCompact,
imageVector = Icons.Default.ViewCompact,
color = MaterialTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfLayoutCompact = it }
)
CompactSwitchSettingItem(
title = "显示分隔线",
checked = BookshelfConfig.bookshelfShowDivider,
imageVector = Icons.Default.ViewCompact,
color = MaterialTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfShowDivider = it }
)
CompactSwitchSettingItem(
title = "标题小字体",
checked = BookshelfConfig.bookshelfTitleSmallFont,
imageVector = Icons.Default.TextFormat,
color = MaterialTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfTitleSmallFont = it }
)
CompactSwitchSettingItem(
title = "标题居中",
checked = BookshelfConfig.bookshelfTitleCenter,
color = MaterialTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfTitleCenter = it }
)
}
}
// Grid Count
val gridCount =
if (isLandscape) BookshelfConfig.bookshelfLayoutGridLandscape else BookshelfConfig.bookshelfLayoutGridPortrait
CompactSliderSettingItem(
title = stringResource(R.string.number_rows_columns),
value = gridCount.toFloat(),
valueRange = 1f..15f,
steps = 14,
onValueChange = {
if (isLandscape) BookshelfConfig.bookshelfLayoutGridLandscape = it.toInt()
else BookshelfConfig.bookshelfLayoutGridPortrait = it.toInt()
AnimatedVisibility(
visible = layoutMode != 1
) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
CompactSwitchSettingItem(
title = "紧凑模式",
checked = BookshelfConfig.bookshelfLayoutCompact,
imageVector = Icons.Default.ViewCompact,
color = MaterialTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfLayoutCompact = it }
)
CompactSwitchSettingItem(
title = "显示分隔线",
checked = BookshelfConfig.bookshelfShowDivider,
imageVector = Icons.Default.ViewCompact,
color = MaterialTheme.colorScheme.surface,
onCheckedChange = { BookshelfConfig.bookshelfShowDivider = it }
)
}
)
}
CompactSliderSettingItem(
title = "标题最大行数",
@@ -74,32 +74,40 @@ object GlassTopAppBarDefaults {
}
return TopAppBarDefaults.topAppBarColors(
containerColor = containerColor,
scrolledContainerColor = scrolledContainerColor
containerColor = applyTopBarOpacity(containerColor),
scrolledContainerColor = applyTopBarOpacity(scrolledContainerColor)
)
}
@Composable
fun containerColor(): Color {
return GlassDefaults.glassColor(
val baseColor = GlassDefaults.glassColor(
noBlurColor = MaterialTheme.colorScheme.surface,
blurAlpha = GlassDefaults.TransparentAlpha
)
return applyTopBarOpacity(baseColor)
}
@Composable
fun scrolledContainerColor(): Color {
return GlassDefaults.glassColor(
val baseColor = GlassDefaults.glassColor(
noBlurColor = MaterialTheme.colorScheme.surfaceContainer,
blurAlpha = GlassDefaults.TransparentAlpha
)
return applyTopBarOpacity(baseColor)
}
@Composable
fun controlContainerColor(): Color {
return GlassDefaults.glassColor(
val baseColor = GlassDefaults.glassColor(
noBlurColor = MaterialTheme.colorScheme.surfaceContainerHighest,
blurAlpha = GlassDefaults.DefaultBlurAlpha
)
return applyTopBarOpacity(baseColor)
}
private fun applyTopBarOpacity(color: Color): Color {
val opacity = (ThemeConfig.topBarOpacity.coerceIn(0, 100)) / 100f
return color.copy(alpha = (color.alpha * opacity).coerceIn(0f, 1f))
}
}
@@ -42,11 +42,11 @@ fun SplicedColumnGroup(
Card(
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(containerColor = Color.Transparent),
modifier = Modifier.fillMaxWidth()
modifier = Modifier
.fillMaxWidth()
.animateContentSize()
) {
Column(
modifier = Modifier
.animateContentSize(),
verticalArrangement = Arrangement.spacedBy(2.dp)
) {
content()